micronaut
- Every Route Registered. Every Request 404'd.
A registered Micronaut route returning 404 under load. The route matched. The controller ran. Mono.zip ate the response.
- The numbers lied until we fixed the ports
Same reactive app on Micronaut, Spring Boot, and Quarkus. The numbers lied until we fixed the harness AND the ports.
- Two ways to mistranslate a retry
Porting @Retryable to Quarkus and Spring produced two silent retry bugs. One was a fix that broke parity. Both passed every test.
- The Throughput Was Always 115
28 mock APIs. Twelve benchmark scenarios. Two codebases. One number: 115 req/s.
- Designed a Reactive Benchmark. Imperative Won.
Built a reactive benchmark with realistic latency. The imperative rewrite survived memory pressure. Reactive didn't.
- 265 req/s on All Three Runtimes (Until You Add a Memory Limit)
Native image, JVM, and virtual threads all hit 265 req/s. Then the memory limit dropped.
- ExecutorType.VIRTUAL Doesn't Exist
The Config Everyone Writes#micronaut: executors: io: type: VIRTUAL Every tutorial. Every "Micronaut + virtual threads" blog post. Every AI suggestion. This is the obvious config. One property, clean intent. It crashes at startup: No enum constant …
- We Removed Reactor. Nothing Got Slower.
We took the entire reactive stack out. R2DBC, Mono, Flux, Reactor Core, loom-carrier, flatMap with its carefully-tuned concurrency arguments. Replaced it with JDBC, HikariCP, and blocking method calls. Same endpoints. Same Netty HTTP server. Same PostgreSQL. …
- Loom Carrier on a Reactive Stack: 78 MB for Free
"Virtual threads don't help reactive apps." You've heard this. Probably said it. The reasoning is sound: a fully reactive stack — Mono/Flux from HTTP client through R2DBC to Netty — never blocks a platform thread. Virtual threads solve blocking. No blocking, …
- flatMap's Second Argument Saved 1.7 Million Requests
Midway through a code review of the reactive pipeline, staring at this line in NeoService.java: .flatMap(neo -> saveAsteroidWithApproaches(sessionId, neo)) That's Flux.flatMap() with one argument. The function. No concurrency limit. Reactor's default: 256 …