Backend Development 9 min read

Performance Comparison of Spring Boot on JVM vs GraalVM Native Image

This article evaluates the startup speed, memory consumption, and request‑handling performance of a simple Spring Boot "Hello World" service when run on the traditional JVM compared with a GraalVM‑compiled native binary, using a MacBook M1 and Bombardier for load testing.

Code Ape Tech Column
Code Ape Tech Column
Code Ape Tech Column
Performance Comparison of Spring Boot on JVM vs GraalVM Native Image

Spring Boot simplifies the creation of production‑ready Java applications by providing embedded servers, starter dependencies, and auto‑configuration, eliminating the need for extensive XML or code generation.

GraalVM can ahead‑of‑time compile Java applications into compact native executables that start up to 100× faster than JVM‑based versions and use significantly less memory and CPU.

The article compares a basic Spring Boot "Hello World" service running on a JVM and as a GraalVM native image. Tests were performed on a MacBook M1 with 16 GB RAM using JDK 21, GraalVM JDK 21, and Spring Boot 3.1.4.

The application source code is:

package com.example.demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@SpringBootApplication
@RestController
public class DemoApplication {
    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }

    @GetMapping("/")
    public String handleRequest() {
        return "Hello World!";
    }
}

The Maven build configuration (pom.xml) includes the Spring Boot starter, test dependencies, the Spring Boot Maven plugin, and the GraalVM native‑image plugin:

<project ...>
  <modelVersion>4.0.0</modelVersion>
  <parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>3.1.4</version>
  </parent>
  <properties>
    <java.version>21</java.version>
  </properties>
  <dependencies>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-test</artifactId>
      <scope>test</scope>
    </dependency>
  </dependencies>
  <build>
    <plugins>
      <plugin>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-maven-plugin</artifactId>
        <configuration>
          <mainClass>com.example.demo.DemoApplication</mainClass>
          <layout>JAR</layout>
        </configuration>
      </plugin>
      <plugin>
        <groupId>org.graalvm.buildtools</groupId>
        <artifactId>native-maven-plugin</artifactId>
        <version>0.9.27</version>
        <extensions>true</extensions>
        <executions>
          <execution>
            <id>build-native</id>
            <goals><goal>compile-no-fork</goal></goals>
            <phase>package</phase>
          </execution>
          <execution>
            <id>test-native</id>
            <goals><goal>test</goal></goals>
            <phase>test</phase>
          </execution>
        </executions>
      </plugin>
    </plugins>
  </build>
</project>

The resulting native binary is approximately 76 MB in size.

Performance tests were executed with 500 000 requests at concurrency levels of 50, 100, and 300 using the Bombardier tool. Results (shown in the original images) indicate that the native image does not provide a clear advantage in request‑throughput over the JVM version for this simple workload.

A scoring system was applied: improvements under 5 % receive no points, 5‑20 % gain 1 point, 20‑50 % gain 2 points, and over 50 % gain 3 points. The final score table (also shown as an image) reflects that GraalVM’s main benefit lies in its reduced memory footprint rather than raw request‑handling speed.

Conclusion: For a trivial "Hello World" service, GraalVM’s native compilation does not significantly outperform the JVM in latency or throughput, but it does achieve markedly lower memory usage, making it a good choice when startup time and memory efficiency are critical.

The author also includes a promotional note encouraging readers to like, share, and subscribe, and advertises a paid knowledge community offering deeper Spring, MyBatis, and micro‑service content.

JavaperformancemicroservicesSpring BootbenchmarkGraalVMnative-image
Code Ape Tech Column
Written by

Code Ape Tech Column

Former Ant Group P8 engineer, pure technologist, sharing full‑stack Java, job interview and career advice through a column. Site: java-family.cn

0 followers
Reader feedback

How this landed with the community

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