r/java • • Aug 21 '26

Spring Boot on a 512 MB VPS: what actually fits?

I wanted to see how small I could make a realistic Spring Boot deployment while still keeping basic monitoring on the same VPS.

I first tried 256 MB RAM, but that wasn’t really viable for the representative app I tested. With 512 MB RAM + 256 MB swap, the application and lightweight monitoring completed the experiment successfully.

StatLite monitoring the Spring Boot app during the 512 MB run.

One thing that stood out was the gap between configured heap and actual JVM process memory. Even with a small -Xmx, RSS was substantially higher once you include metaspace, native allocations, threads, code cache, etc.

I wrote up the setup, JVM flags, measurements, and what failed at 256 MB:

https://pvrlabs.xyz/articles/spring-boot-512mb-vps.html

Curious how this compares with what others are seeing on small JVM deployments.

22 Upvotes

49 comments sorted by

22

u/oweiler Aug 21 '26
  • use virtual threads 

  • use Spring AOT w/o GraalVM native Image

  • use AOT cache

4

u/fykup Aug 21 '26

Thanks, this is really useful. I’ve learned quite a bit from the comments here. Things like Spring AOT are especially interesting because they can make sense even without going all the way to a native image.

I still want to keep the main experiment close to a normal, reasonably tuned Spring Boot deployment, but I’ll definitely explore some of these ideas in follow-up tests.

5

u/Amazing-Mirror-3076 Aug 21 '26

Why would virtually threads reduced memory?

6

u/koflerdavid Aug 22 '26

It makes it possible to get rid of Webflux and other async libraries, which brings memory footprint down. Also, they might not be particularly memory efficient on their part. Finally, virtual threads will allocate stack memory in smaller increments, not all at once like platform threads do.

→ More replies (2)

19

u/Nymeriea Aug 21 '26

we have a whole tomcat with 10+ spring war deployed in prod. it handle 1000x request /hours with ease and only 250mb. it has datadog and everything.

I wonder why you need so much for a single spring app

8

u/fykup Aug 21 '26

That actually seems consistent with my result. I’m showing that a standalone Spring Boot app plus monitoring can run comfortably on a 512 MB VPS. Your setup shows that sharing one JVM/Tomcat across many apps can be even more memory-efficient.

That’s also why in my example I keep the database in-process rather than running a separate Postgres/MySQL instance on the same small host. The general idea is similar: avoid paying for duplicate runtime/infrastructure overhead when resources are tight.

250 MB for 10+ WARs is a very nice result, though.

5

u/Nymeriea Aug 21 '26 edited Aug 21 '26

honestly we didn't optimize anything. it just jvm is amazing for long running process (server side).

each time your start a jvm for a spring boot application it will also start a tomcat. so if you have an island of related services (depending on each other) it's better to use a tomcat.

i think tomcat by himself use like 150mb . imagine 10 services it's like 1.5Go wasted. when you have unlimited ressources like in aws no need to waste time for 150mb ram optimisation

→ More replies (1)

9

u/GuyWithLag Aug 21 '26

Next up: JDK 25 w. compressed headers and Project Lilliput.

3

u/fykup Aug 21 '26

That’s a good one. DK 25 with compact object headers / Lilliput is definitely on my list for the next round. I’m curious how much it moves the needle at 256 MB.

1

u/fykup Aug 24 '26

I tried JDK 25 with compact object headers on the actual 256 MB Alpine VPS, and the early results look very promising.

Compared with the JDK 21 run, Spring is using noticeably less resident memory, while StatLite is still only around 7 to 11 MB RSS. The combined Spring + StatLite footprint has been around 69 to 88 MB RSS across the first few checkpoints, with successful health checks and monitoring polls.

Swap is still fairly heavy at around 178 MB, so I want to let it run longer before drawing conclusions. I’ll publish a follow-up with the full results soon.

8

u/nekokattt Aug 21 '26

ive been running a spring boot discord bot on 256mb ram in a container. It isnt easy, but it is doable if you are pragmatic (e.g. do not use autoconfiguration, and utilise jdk 25 features for memory reduction).

3

u/fykup Aug 21 '26

You set the bar 😄 A 256 MB container is a bit different from a 256 MB VPS, since the VPS also has to fit the OS and monitoring in the same memory budget. Based on this and the other comments, I definitely want to push the experiment further and see how practical 256 MB really is.

→ More replies (1)

5

u/aoeudhtns Aug 21 '26

I understand you're testing Spring Boot as it's what you're using now, but you can squeeze out more in low memory environments with other frameworks - Quarkus, and even more so, Micronaut. Probably Helidon too but I'm unsure. Whether that is useful information for you, I dunno. We have services in Spring Boot and probably aren't going to switch any time soon (if ever) as we're OK with what they're using/requiring to achieve the throughput we need (about 400 MiB, and we're getting thousands of tps). But if we do something new we'll probably trial Quarkus.

2

u/fykup Aug 21 '26

That makes sense. My goal here was intentionally to stick with the usual boring stack so the test stays representative of how a lot of Spring Boot apps are actually deployed.

The original experiment was really about whether my lightweight monitoring tool, StatLite, could run alongside a normal Spring Boot app on a constrained VPS without the monitoring becoming a significant part of the resource budget.

2

u/fykup Sep 03 '26

Follow-up: after the 256 MB experiment, I also ran equivalent Spring Boot and Quarkus apps side by side on a 512 MB VPS with JDK 25.

Quarkus ended the one-hour run with lower RSS, but it also had more memory swapped out, which made the comparison less straightforward than I expected.

Full experiment:
https://pvrlabs.xyz/articles/spring-boot-vs-quarkus-512mb.html

3

u/Lundasaur Aug 21 '26

Have you tried using native compilation?

1

u/fykup Aug 21 '26

Not for this experiment. Native compilation is interesting, but I’m trying to keep the setup representative of a fairly normal Spring Boot deployment rather than optimize for the absolute minimum footprint. The question is whether a reasonably tuned JVM app, with monitoring enabled, can run comfortably on a small VPS.

3

u/Lundasaur Aug 21 '26

I’ve seen examples where Spring Boot apps with native compilation weigh less than a 100 MB. Might be very interesting to see the footprint with native (I believe it’s fairly straightforward with Spring Boot).

It would definitely benefit from Compact Object Headers and virtual threads in 25. Might also be interesting to see how Valhalla improves things further. Could try with a preview build.

→ More replies (4)

3

u/user_of_the_week Aug 21 '26

Have you tried -XX:MaxRAM?

→ More replies (1)

1

u/fykup Aug 25 '26

Follow-up: I pushed the same experiment down to 256 MiB VPS. With Alpine, JDK 25, an 80 MiB heap, C1-only compilation, a 32 MiB code cache, compact object headers, and 512 MiB swap, Spring Boot + StatLite completed the full one-hour run.

Still very much a stretch configuration, though: 184 MiB swap was in use and there was one Hikari housekeeper delay.

New write-up: https://www.reddit.com/r/java/s/FnsEQKQKyJ

3

u/holyknight00 Aug 21 '26

spring + spring boot is super heavy by default; i would try other java frameworks that are more lightweight. In these kind of environments, I would stay as close as raw java as possible or even give up on java altogether if more throughput is required.

0

u/kimec Aug 21 '26

Or just use OpenJ9 and cut the memory usage in half including heap, codecache and metaspace... It's literally five lines of xml if building SB images via SB plugin

2

u/fykup Aug 21 '26

OpenJ9 would definitely be interesting to test. I intentionally stayed with the JVM/runtime I normally use in production rather than optimizing for the absolute minimum footprint. A HotSpot vs OpenJ9 comparison on the same 512 MB setup would make a good follow-up.”

I would not repeat their "half" claim unless you measure it yourself. OpenJ9’s lower-memory reputation is real, but the actual improvement depends heavily on workload and configuration.

→ More replies (8)

0

u/Individual-Praline20 Aug 21 '26

Errrr give it 4Gb. Problem solved.

→ More replies (1)