This example project uses GraalVM Native Image, Kotlin, and Quarkus to create an instant startup and low memory footprint web service.
Install the Quarkus CLI with SDKMan: sdk install quarkus
Install GraalVM 24 with SDKMan: sdk install 24-graal
quarkus build --native -Dquarkus.native.additional-build-args="-Ob"
You can then execute your native executable with: ./target/code-with-quarkus-1.0.0-SNAPSHOT-runner
An application for gathering profiling data can be created with:
quarkus build --native -Dquarkus.native.additional-build-args="--pgo-instrument"
When you now run the application with: ./target/code-with-quarkus-1.0.0-SNAPSHOT-runner
And provide some payload with hey: hey -n 1000000 http://localhost:8080/hello
A file default.iprof
is created. Now this file can be fed into an optimized image build:
quarkus build --native -Dquarkus.native.additional-build-args="default.iprof,--gc=G1,-O3,-march=native"
The additional parameters select the G1 garbage collector with --gc=G1
, the highest optimization level -O3
and
-march=native
enables the use of any instruction that is available on the build system machine.
The optimized executable is generated at: ./target/code-with-quarkus-1.0.0-SNAPSHOT-runner
The resulting executable starts in less than 10 milliseconds!
INFO [io.quarkus] (main) code-with-quarkus 1.0.0-SNAPSHOT native (powered by Quarkus 3.26.3) started in 0.007s. Listening on: http://0.0.0.0:8080
The peak performance with profile-guided optimizations is within 3% of the just-in-time compiled version.
When starting with -Xmx128m
, the JVM version takes around 500Mb of memory compared to the native version at only 135Mb, so a factor of 3 lower memory utilization.