Friends of OpenJDK Today

Web App Startup in 3ms with RIFE2 and GraalVM

February 21, 2023

Author(s)

  • Geert Bevin

    Software Engineering, Musical Instrument Design, UI/UX Design, Product Design

RIFE2 applications already launch quickly with a regular JVM thanks merely calling Java methods, lambdas and doing object instantiations at startup. There are no annotations to scan for, nor any declarations or config files to parse and resolve.

The RIFE2 v1.3.0 release introduced experimental support for GraalVM Ahead-Of-Time compilation with native-image, reducing the startup time of the bootstrap project from 177ms to an incredible 3ms.

Try it out yourself

In order to try this out, you can download the latest GraalVM JDK 19 distribution, and follow the steps to install native-image on your machine.

Next, clone the RIFE2 bootstrap project, make it your current directory and create an UberJar using Gradle.

./gradle2 uberjar

If you want to, you can first try the generated UberJar to get a feel of its performance and behavior:

java -jar app/build/libs/hello-uber-1.0.jar

The embedded Jetty server will start and in a little under 200ms you should be able to access http://localhost:8080/hello to see a Hello World page.

Now, you create a single native executable with GraalVM using the following command:

native-image --no-fallback --enable-preview -jar hello-uber-1.0.jar

Starting that one up is even easier with the single executable that now contains everything:

./hello-uber-1.0

Microbenchmark numbers

I ran the previous instructions on my AMD Ryzen 9 5950X 16 Core 128GB dedicated Ubuntu Linux server and then called siege -c 10 -r 2000 -b http://localhost:8080/hello to measure the performance:

These were the key points:

  • application startup in 3ms
  • standalone native executable size is 38MB
  • using siege locally with a concurrency of 10 x 2000 requests, gives ~33898 trans/sec
  • after the test, used up 281.7MB RES and 24.8MB SHR memory, accounts for 0.2% of memory

In comparison, launching the Uber jar with the JVM on the same machine:

  • application startup in 177ms
  • uber jar size is 4.7MB but requires a separate JVM installation
  • using siege locally with a concurrency of 10 x 2000 requests, gives ~44444 trans/sec
  • after the test, used up 1.7GB RES and 39.7MB SHR memory, accounts for 1.3% of memory

NOTE: RIFE2 support for GraalVM native-image is still in experimental. There's no solution yet to replace the features of the RIFE2 Java agent, and it's only been tested in a limited context.

Share your thoughts

I'm curious to hear how GraalVM native-image is faring for you.

What are you already using it for or what are your plans?
How could I further improve RIFE2 to better support Ahead Of Time compilation?

Feel free to connect on Mastodon or to join me on Discord, I would love to hear from you!

Topics:

Related Articles

View All

Author(s)

  • Geert Bevin

    Software Engineering, Musical Instrument Design, UI/UX Design, Product Design

Comments (0)

Your email address will not be published. Required fields are marked *

Highlight your code snippets using [code lang="language name"] shortcode. Just insert your code between opening and closing tag: [code lang="java"] code [/code]. Or specify another language.

Save my name, email, and website in this browser for the next time I comment.

Subscribe to foojay updates:

https://foojay.io/feed/
Copied to the clipboard