A side-by-side JVM-mode comparison on a memory-starved VPS, run through StatLite's new Quarkus support. The results are messier than a simple 'X uses less RAM' headline.
5 min read
This is a summary of a single published experiment, Spring Boot vs Quarkus on a 512 MB VPS, which put equivalent Spring Boot and Quarkus applications on the same 512 MiB VM to exercise the Quarkus monitoring support just added to StatLite. StatLite already monitored Spring Boot apps; this run tested both integrations at once on a genuinely small server.
Both apps ran the same "Star Pulse" workload: every five minutes, fetch star/fork/watcher counts for the same three GitHub repositories and store the results in H2. Both got:
-Xmx80m heap ceilingThe host was Ubuntu 24.04, one vCPU, with the guest exposing 452 MiB of RAM and 256 MiB of persistent swap. One StatLite process monitored both applications and the host itself. The source is explicit that this is a JVM-mode comparison, not a native-image comparison, and that it's independent of the earlier single-application 512 MB and 256 MB JDK 25 runs on this same site.
The full JVM flags, versions, demo application source, selected RSS/PSS/VmSwap measurements, checkpoints, kernel/OOM evidence, restart chronology, methodology, and stated limitations are in the published experiment record. Full archives, databases, and private metadata are omitted from that record.
The article deliberately reports three distinct runs rather than blending them into one number:
| Observation | What it answers |
|---|---|
| Health-enabled hour, Sep 1, 2026 | Controlled comparison. Both apps stayed up, zero restarts. |
| Memory-residency follow-up | Why RSS moved the way it did, including swap effects. |
| Sep 2, 2026 observation | Operational failure: not enough headroom, Spring was OOM-killed. |
At the settled checkpoint in the memory-residency follow-up, Spring Boot sat at about 112 MiB RSS while Quarkus was about 145 MiB. Over the following hour the picture reversed:
| Framework | Settled RSS | 60-min RSS | 60-min JVM heap used | 60-min swap residency |
|---|---|---|---|---|
| Spring Boot | ~112 MiB | ~154 MiB | ~50.3 MB | ~66 MiB |
| Quarkus | ~145 MiB | ~83 MiB | ~33.1 MB | ~91 MiB |
Quarkus's RSS fell substantially, but its heap didn't fall with it — heap grew from about 28.0 MB to 33.1 MB while swapped memory grew from about 29 MiB to 91 MiB over the same period. The article's own reading of this: Linux was paging Quarkus more aggressively, so "RSS alone was misleading" as a metric. Even accounting for that, Quarkus ended up with the smaller heap and smaller resident working set at that comparison point, while Spring moved the other direction.
The article is careful to flag that this ranking isn't stable across runs on this machine. The separate health-enabled hour finished with zero restarts and the opposite RSS ranking — about 61 MiB for Spring and 156 MiB for Quarkus. Both results are reported; neither is treated as the "real" number.
The VM first exhausted its memory and swap margin during Ubuntu package maintenance. Spring was OOM-killed, and the restart handling from that package activity also restarted the application services — showing how little headroom the machine had for ordinary OS housekeeping, separate from the framework comparison itself.
The more directly relevant result came after that maintenance pressure cleared. Spring and Quarkus were restarted with the same JDK 25 and -Xmx80m configuration, and a fresh one-hour observation began. About 41 minutes in, swap was again effectively exhausted and the kernel OOM-killed Spring. Spring restarted automatically; Quarkus and StatLite did not restart, and the final health checks succeeded. The article is explicit that this later OOM wasn't caused by the earlier apt transaction, and doesn't rule out other contributing OS activity. Its stated conclusion: this VM's 452 MiB of RAM plus 256 MiB of swap didn't provide enough headroom to guarantee reliable survival of both JVM applications for an hour.
StatLite itself stayed small — roughly 10 to 15 MiB RSS at the relevant checkpoints — and kept monitoring through the Spring restart, recording the health failure and the recovery. The workload also hit unauthenticated GitHub rate limits, producing upstream 403 responses documented in the experiment record; these affected application polling but were not StatLite or framework crashes.
The article notes that its 24-hour dashboard views cover the morning maintenance window as context, not the timed comparison itself, and that the "Runtime memory MB" shown on those dashboards is JVM heap, not RSS.
This draft summarizes the linked source only. The author's own hands-on testing, setup notes, and take on what this means for running either framework on small VPS instances have not yet been added — the judgement calls here are deliberately left open.
I have been testing the Quarkus support we just added to StatLite. Since StatLite already monitors Spring Boot applications, I put equivalent Spring Boot and Quarkus applications side by side to exer…
Generators, lazily: what yield actually does to a function.
Summary12 Oct 20261 min read
Hands-on gc.collect cost empty vs cyclic garbage lab: real collect latency plus reclaim counts, measured on Linux localhost today in this lab for SREs.
Hands-on1 Oct 20264 min read
Hands-on1 Oct 20264 min read