Field notes
All writingRSSAbout

Spring Boot vs Quarkus on a 512 MB VPS: what the numbers actually showed

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.

9 September 2026·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.

The setup

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:

  • Spring Boot 3.5.5 vs Quarkus 3.39.1
  • JDK 25.0.4 on both
  • The same -Xmx80m heap ceiling
  • The same JVM flags
-Xms16m
-Xmx80m
-Xss256k
-XX:+UseSerialGC
-XX:TieredStopAtLevel=1
-XX:ReservedCodeCacheSize=32m
-XX:+UseCompactObjectHeaders

The 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.

Three separate observations, kept separate

The article deliberately reports three distinct runs rather than blending them into one number:

ObservationWhat it answers
Health-enabled hour, Sep 1, 2026Controlled comparison. Both apps stayed up, zero restarts.
Memory-residency follow-upWhy RSS moved the way it did, including swap effects.
Sep 2, 2026 observationOperational failure: not enough headroom, Spring was OOM-killed.

Quarkus started larger, then shrank

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:

FrameworkSettled RSS60-min RSS60-min JVM heap used60-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.

What happened when memory actually ran out

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.

Monitoring overhead and other caveats

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.

Stated takeaways

  • Startup RSS alone was a misleading comparison point — Quarkus started higher, then fell below Spring's after an hour.
  • Under sustained memory pressure, Quarkus in this run ended with a smaller heap and smaller resident working set than Spring Boot, but the ranking flipped in the separate health-enabled hour, so it isn't treated as settled.
  • 452 MiB of RAM plus 256 MiB of swap was too tight for reliable operation of both JVMs; Spring was eventually OOM-killed once package-maintenance pressure had cleared.
  • The article frames all of this as evidence about behavior under extreme memory pressure, where Linux paging and OOM handling become part of the result — not a clean, definitive memory benchmark between the two frameworks. It suggests a higher-headroom follow-up on a less constrained VM as a future experiment to isolate the frameworks' own behavior from those side effects.

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.

spring bootquarkusjvmmemory managementvpsoom killerlinux pagingjdk 25

Sources

  1. 01
    Spring Boot vs Quarkus on a 512 MB VPS

    I have been testing the Quarkus support we just added to [StatLite](https://pvrlabs.xyz/statlite/). Since StatLite already monitors Spring Boot applications, I put equivalent Spring Boot and Quarkus applications side by side to exercise both integrations and see how they behaved on a genuinely small server. The setup was intentionally demanding: both apps got one Star Pulse workload, one JDK 25 build, one `Xmx80m` profile, and one 512 MiB VM with 256 MiB of swap. One StatLite process monitored

More from the field

  • Setting up AI Coworkers with OpenBot

    10 Sept 2026

  • XZ Utils Backdoor: A Technical Deep Dive

    10 Sept 2026

  • Introducing CUDA Rust: Two Tracks for Writing GPU Kernels

    10 Sept 2026

All writingArchiveTopicsAboutPrivacyRSS

© 2026 Field notes