GraalVM Native Image Tips & Tricks

Elastic infrastructure that scales up & down based on demand is not just a “serverless” fad but an operational model which reduces cost and waste. Yet there is a little devil lurking under the covers… When an application / microservice needs to spin up based on demand there can be some lag as the application needs to be downloaded to the node, potentially a VM needs to be started, the application itself needs to be started, and potentially local caches need to be hydrated. In traditional enterprise systems this “cold start” process can realistically take tens of minutes. But it’s near impossible to have demand-based scaling when things take that long to start.

GraalVM is a Java Virtual Machine implementation that addresses parts of the “cold start” problem by doing Ahead-Of-Time (AOT) compilation on JVM-based applications. GraalVM can create a “native image” of your application so that it no longer needs to run inside a JVM. This can reduce startup time and in some cases improve overall performance. The native images can also be much smaller than the usual OS + JVM + all dependency JARs. For example, a recent application I was working on went from a pretty trim 208MB docker image (OS + JVM + deps + app) that started in 2 seconds, down to 14MB and a 0.5s startup time. Sounds amazing! But there are some caveats, tips, and tricks I’d like to share with you.