The Memory Benchmark Nobody Asked For
Native image, memory, and the benchmark nobody warned you about.
A Micronaut 5.0.0 Space Observatory app — 16 REST endpoints, reactive R2DBC, 7-table PostgreSQL schema. The challenge: run it in a 256 MB container with swap disabled. GraalVM native image, garbage collector shootouts, invisible JVM memory, AOT bugs, and reactive backpressure tuning.
- Micronaut 5 Native Image: 14 Entries vs 1,913
- Native Image vs JVM at 128 MB
- The Observability Tax
- Every GC Failed at 256 MB (Except the Boring One)
- 107 MB of Invisible JVM RAM
- Your JVM Reports 151 MB. Your Container Uses 248.
- Three Bugs in a Trenchcoat Pretending to Be One Hang
- The AOT Hang That Wasn’t
- Seven Fixes, Zero Errors
- flatMap’s Second Argument Saved 1.7 Million Requests
- Loom Carrier on a Reactive Stack: 78 MB for Free
- We Removed Reactor. Nothing Got Slower.
- Error Is Not Exception: Micrometer’s Silent CPU Metric on Native Image
- ExecutorType.VIRTUAL Doesn’t Exist
- 265 req/s on All Three Runtimes (Until You Add a Memory Limit)
- Designed a Reactive Benchmark. Imperative Won.
- The Throughput Was Always 115
- Quarkus 12,563 vs Spring 820 (Both Numbers Are Wrong)
- -Xmx Won’t Save Your Native Image
- 1% CPU and 6-Second Latency
- Two ways to mistranslate a retry
- Three Front Doors, One Engine
- Six OOMs and a Connection Pool
- Four Bugs the Tests Couldn’t See
- Every Route Registered. Every Request 404’d.
- 16,700 Classes Before Your First Request
- Eight Connections, Zero Available
- 2492, 2495, 2508
- Native Image Grew to 734 MB