Project Leyden: Faster Java Startup Without GraalVM’s Pain, and What You Give Up
Java startup has long been the price of a smart runtime. GraalVM Native Image fixed it by replacing the JVM, but that fix came with strings attached. Project Leyden takes a gentler road. So what exactly do you win, and what do you quietly lose?
First, a Timeline Check
Before we compare anything, let’s get the dates straight, because they are easy to mix up. Project Leyden has been shipping in small pieces. Method profiling (JEP 515) arrived in JDK 25, which is a long-term support release. However, the headline feature, full ahead-of-time code compilation, did not make JDK 26 or JDK 27.
In fact, JDK 27 reached general availability on September 15, 2026 without it. Instead, JEP 544 lists JDK 28 as its release, with a status of “Proposed to Target”. That means it is promising, but it is not final yet.
| JEP | What it does | JDK | Status |
|---|---|---|---|
| 483 | Caches loaded and linked classes | 24 | Delivered |
| 514 | One-command cache creation | 25 (LTS) | Delivered |
| 515 | Caches method profiles for faster warmup | 25 (LTS) | Delivered |
| 516 | Cache works with any garbage collector, including ZGC | 26 | Delivered |
| 544 | Caches compiled native code | 28 (proposed) | Proposed to Target |
Sources: the JEP pages themselves, plus the BackendBytes JEP-to-JDK mapping, which was checked against the OpenJDK pages in September 2026.
Where GraalVM’s Pain Comes From
GraalVM Native Image compiles your app into a standalone executable. As a result, it starts in milliseconds and uses little memory. Yet it relies on a “closed-world” rule: everything must be known at build time.
That rule creates real work. According to the GraalVM metadata docs, Java cannot load new classes at run time in a native image, and dynamic features such as reflection need extra metadata. Moreover, the build itself is heavy, so teams usually keep a normal JVM build for daily development. None of this is a flaw. It is simply the cost of removing the JVM.
How Leyden Takes a Different Road
Leyden keeps the JVM. Instead, it moves work earlier in time. You run your app once in a “training run”, and the JVM saves what it learned into an AOT cache file. Later, production runs load that cache and skip much of the startup work.
Because it is still HotSpot underneath, reflection, dynamic class loading and your usual tools keep working. Furthermore, if the cache does not fit, the JVM falls back to its normal interpreter and JIT. Therefore, the worst case is an ordinary start, not a crash.
Try It Yourself
The workflow needs JDK 25 or newer. I tested these two commands on Temurin 25.0.4.1 with a tiny stream-based program packed into app.jar. The first command trains and builds the cache, and the second one uses it.
java -XX:AOTCacheOutput=app.aot -cp app.jar HelloStream java -XX:AOTCache=app.aot -cp app.jar HelloStream
Both commands printed the expected output. Keep one detail in mind: the one-step command runs a second JVM to assemble the cache. BackendBytes notes, citing JEP 514, that this assembly step uses its own heap of the same size, so memory-limited CI runners may need the two-step workflow.
What the Numbers Say
To see the effect, I measured two small programs on JDK 25.0.4.1: the stream example above, and a slightly busier one that uses records, regex, collectors and a thread pool. Each case ran 25 times, and the chart shows the median wall-clock time in milliseconds.

The stream program went from 75 ms to 47 ms, about 37% faster. The busier program dropped from 151 ms to 79 ms, roughly 48% faster. These results match the official picture. For example, JEP 483 reports Spring PetClinic starting in 2.604 seconds instead of 4.486 seconds, a 42% improvement. In addition, JEP 515 reports a 19% gain on a tiny warmup example, from 90 ms to 73 ms.
The Real Trade-Off
Leyden is not “GraalVM without the cost”. It is a different bargain, and it has its own bills.
What You Still Pay
First, you still ship and run a full JVM, so memory use stays JVM-sized. Second, you add a training step to your build, and a poor training run gives weaker results. As SoftwareMill’s JEP 514 and 515 explainer points out, training quality directly affects the gain. Third, the cache is tied to your setup. Per JEP 483, as summarized by BackendBytes, training and production must share the same JDK release, OS and CPU architecture.
Finally, there is file size. My caches were 10.0 MB and 12.1 MB for tiny programs. A third-party breakdown lists about 130 MB for PetClinic, so budget for it in container images.
What JEP 544 May Change
The next step is to cache optimized native code, not only profiles. If it lands as planned, startup gains should grow. BackendBytes, summarizing the JEP’s benchmarks on five framework apps with two cores, reports a rise from about 50 to 70% faster with the cache alone to about 65 to 80% with AOT code added.

The draft JEP also says support starts with x64 and AArch64 processors only.
Leyden or GraalVM?
| Leyden AOT cache | GraalVM Native Image | |
|---|---|---|
| Runs on | Standard HotSpot JVM | Standalone native binary |
| Startup | Faster, still JVM speed | Milliseconds |
| Memory | About JVM level | Much lower |
| Code changes | None expected | Metadata for reflection and similar |
| Dynamic features | Kept | Restricted by closed world |
| Maturity | Shipping in steps, code caching proposed | Mature, monthly releases |
In practice, start with Leyden if you want a cheap win and zero compatibility risk. Choose Native Image when memory density or tiny start times matter most, and you can afford the build work.
What We Have Learned
Project Leyden speeds up Java by moving startup work into a training run and saving it in an AOT cache. Class loading and linking arrived in JDK 24, while one-command setup and method profiling arrived in JDK 25 LTS, and ZGC support followed in JDK 26. Full AOT code compilation is not in JDK 27, because JEP 544 is proposed for JDK 28. In my small tests, the cache cut startup by about 37% and 48%, which fits the official 42% PetClinic figure. The trade-off is clear: you keep the JVM, its tools and its flexibility, but you also keep its memory use, and you must manage a training run and a cache file. In short, Leyden is the low-risk first step, and Native Image remains the choice for extreme footprint goals.

