Why the Hell Do I Need Reactive Anyways?
If you know me, you know I’m a loud and proud evangelist of reactive programming. But why do I prefer it over the good old traditional MVC? Let me break it down for you in my usual no-nonsense style.
The Problem with Traditional MVC
Here’s the typical scenario: you’ve got an application with a pool of threads. Every time a new request comes in, the app assigns a thread to handle that request. Kind of simple, right? Well, simplicity comes with a cost.
Imagine this: one of those threads is tasked with calling an external API or running a long database query. What happens to that thread? It just sits there, idle, waiting for a response. It’s not doing any other work; it’s essentially a wasted resource during that waiting period☠️.
To make matters worse, each thread hogs up to 1MB of stack memory. Let’s say you’re running an app on a server with 1GB of RAM, expecting 400 concurrent requests. That’s 400 threads, which means 400MB of your memory is gone just managing threads. And we haven’t even started talking about the actual work those threads are supposed to do. Microservices promised to make our lives easier, but they also brought their own baggage. With microservices, you get a lot of network calls, and this increases the problem of threads being blocked. Essentially, you’ve got more waiting threads burning through your resources.
And so:
This is where reactive programming, specifically with Flux and WebFlux, changes the game. It uses system resources far more efficiently. It doesn’t let threads sit around doing nothing. Instead of waiting for a response, threads are free to handle other tasks. When the response finally arrives, the system notifies the thread to complete the pending operations.
This non-blocking approach allows your application to handle far more work with the same number of threads.
The Proof Is in the Benchmarks
Reactive-based applications have a significantly higher throughput compared to traditional web applications, especially when handling a high volume of concurrent requests. I ran some benchmarks to prove it, and the results speak for themselves. (I posted those benchmarks on LinkedIn; check them out here.)
Mono and Flux
With WebFlux, your backend service returns a publisher—a Mono or Flux—rather than plain old data structures like lists.
In the reactive world:
- A Mono represents a single value.
- A Flux represents a stream of values.
This is powerful because the subscriber (like a browser or another microservice) receives the data as it’s published. No need for bulk requests or polling. Data streams to the subscriber as it becomes available—a concept called Server-Sent Events.
Here’s a simple example to show what I mean:
Controller:
1
2
3
4
@GetMapping(value = "table/{input}/stream", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
public Flux<Response> multiplicationTableStream(@PathVariable int input) {
return mathService.multiplicationTable(input);
}
Service:
1
2
3
4
5
6
public Flux<Response> multiplicationTable(int input) {
return Flux.range(1, 10)
.delayElements(Duration.ofSeconds(1))
.doOnNext(i -> System.out.println("reactive math service processing " + i))
.map(i -> new Response(i * input));
}
Reactive is smarter too 💡
In the MVC model, the backend processes data only after the request is completed. If the user cancels the request mid-way (say, by clicking the browser’s “X” button), the backend doesn’t know and keeps working unnecessarily.
But in a reactive approach, the backend stops processing immediately when the user cancels the request. That’s a massive win in terms of efficiency and resource utilization.
So, why the hell do you need reactive? Because it’s faster, smarter, and resource-efficient. It’s built for the modern world of microservices and high-concurrency demands. If you’re not convinced yet, check out the benchmarks I posted on LinkedIn here. They’ll make a believer out of you.