Cloud Native 9 min read

Hands‑On Experience with Spring Boot 3.2, JDK 21, and GraalVM Native Images

The article walks through building a Spring Boot 3.2 application with JDK 21 as a GraalVM native image, compares binary and jar deployments, benchmarks against Go and Rust implementations, and concludes that AOT‑processed native images dramatically reduce startup time and memory usage despite long compile times.

Java Architect Handbook
Java Architect Handbook
Java Architect Handbook
Hands‑On Experience with Spring Boot 3.2, JDK 21, and GraalVM Native Images

Binary (native) deployment

Define a minimal Spring Boot application with @RestController and @GetMapping("/customers") that returns a Set.of of three Customer records. Build a GraalVM native image and launch it. Startup completes in sub‑second time. Load test using ab -c 50 -n 10000 reports:

Requests per second:    7076.39 [#/sec] (mean)
Time per request:       7.066 ms (mean)
Memory usage: ~70 MB (peak), ~20 MB idle

The binary cannot be monitored with JConsole or Arthas because it runs without a JVM.

Jar deployment

The same source is packaged as a regular JAR (size 19 MB). Load testing yields:

Requests per second:    557.72 [#/sec] (mean)
Time per request:       89.651 ms (mean)
Memory usage: ~200 MB (peak), ~160 MB idle

Performance improves after JVM warm‑up, confirming the need for pre‑warming.

Go comparison

An equivalent Go program using only the standard library serves /customers. The binary size stays around 10 MB (up to 20 MB with a framework). Load test results:

Requests per second:    7247.68 [#/sec] (mean)
Time per request:       6.899 ms (mean)
Memory usage: ~10 MB idle

Rust comparison

An Actix‑web Rust service is built. Idle memory consumption is about 3 MB and rises to roughly 6 MB under load. Load test results:

Requests per second:    9163.48 [#/sec] (mean)
Time per request:       5.456 ms (mean)
Memory usage: ~6 MB peak

Compilation time on the author’s machine is notably long (≈ 1 ½ minutes):

$ time cargo build
cargo build  213.00s user 23.08s system 258% cpu 1:31.39 total

Build cost

Generating the native image takes about 15 minutes on a 2017 MacBook Pro:

Finished generating 'demo' in 14m 33s.
[INFO] BUILD SUCCESS
[INFO] Total time:  15:45 min
[INFO] Finished at: 2023-12-01T17:00:21+08:00

Conclusion

AOT‑processed native images for Spring Boot eliminate slow JVM startup, pre‑warm requirements, and high memory consumption. The trade‑off is a very slow build process (≈ 15 minutes). This demonstrates significant progress of Java in cloud‑native environments.

References

[1] https://spring.io/blog/2023/09/09/all-together-now-spring-boot-3-2-graalvm-native-images-java-21-and-virtual

[2] https://start.spring.io/

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

RustGoPerformance BenchmarkSpring BootGraalVMNative ImageJDK 21
Java Architect Handbook
Written by

Java Architect Handbook

Focused on Java interview questions and practical article sharing, covering algorithms, databases, Spring Boot, microservices, high concurrency, JVM, Docker containers, and ELK-related knowledge. Looking forward to progressing together with you.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.