惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

F
Full Disclosure
WordPress大学
WordPress大学
小众软件
小众软件
Cloudbric
Cloudbric
AWS News Blog
AWS News Blog
腾讯CDC
量子位
人人都是产品经理
人人都是产品经理
大猫的无限游戏
大猫的无限游戏
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
V
Vulnerabilities – Threatpost
Scott Helme
Scott Helme
Hugging Face - Blog
Hugging Face - Blog
博客园_首页
C
CXSECURITY Database RSS Feed - CXSecurity.com
The Hacker News
The Hacker News
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
IT之家
IT之家
Jina AI
Jina AI
Attack and Defense Labs
Attack and Defense Labs
S
SegmentFault 最新的问题
Simon Willison's Weblog
Simon Willison's Weblog
The Cloudflare Blog
阮一峰的网络日志
阮一峰的网络日志
T
Tailwind CSS Blog
Last Week in AI
Last Week in AI
博客园 - 【当耐特】
Google Online Security Blog
Google Online Security Blog
美团技术团队
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
V
Visual Studio Blog
罗磊的独立博客
L
LINUX DO - 最新话题
博客园 - Franky
博客园 - 叶小钗
Apple Machine Learning Research
Apple Machine Learning Research
The Last Watchdog
The Last Watchdog
J
Java Code Geeks
AI
AI
C
Cisco Blogs
酷 壳 – CoolShell
酷 壳 – CoolShell
C
Cyber Attacks, Cyber Crime and Cyber Security
Cisco Talos Blog
Cisco Talos Blog
博客园 - 三生石上(FineUI控件)
雷峰网
雷峰网
Help Net Security
Help Net Security
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
云风的 BLOG
云风的 BLOG
I
Intezer
S
Securelist

Piotr's TechBlog

Deep Dive into Kafka Offset Commit with Spring Boot Claude Code Template for Spring Boot Local AI Models with LM Studio and Spring AI AI Models in Containers with RamaLama Claude Code on OpenShift with vLLM and Dev Spaces Create Apps with Claude Code on Ollama Spring AI with External MCP Servers Istio Spring Boot Library Released Startup CPU Boost in Kubernetes with In-Place Pod Resize
Speed up Java Startup with Spring Boot and Project Leyden
piotr.minkowski · 2026-03-19 · via Piotr's TechBlog

This article explains how to use the new Java features provided within Project Leyden to speed up Spring Boot application startup. Project Leyden is an OpenJDK initiative focused on making Java applications start faster, warm up quicker, and use less memory. It builds on CDS (Class Data Sharing) and Ahead-of-Time optimizations to move selected computations out of runtime and perform them earlier, reducing work during application startup and execution. It is currently in the experimental phase. So, it is not a part of the standard JDK distribution, and you should definitely not try it in production. To use it, you need the so-called early access build of the JDK, which is available here. I downloaded the latest version, which is based on an incomplete JDK 26 build.

By the way, there are two early access builds of Project Leyden right now: EA1 and EA2. In this article, I’m referring to the early access 2. You can compare both versions in the project’s release notes. Here are the release notes for EA1. On the other hand, here are the release notes for EA2. There are significant differences between the two versions, for example, in the JVM flags used.

Other Articles

On my blog, you’ll find several other articles that discuss ways to optimize Java application startup times. For example, the following article explains how to use the CRaC approach to reduce the startup time of Java applications on Kubernetes. This post, on the other hand, shows how to temporarily increase the CPU resources available to our application just while it’s starting up on Kubernetes.

If you’re interested in Java application performance, particularly in a Kubernetes environment, you can read more about it in my latest book, Hands-On Java with Kubernetes.

Source Code

Feel free to use my source code if you’d like to try it out yourself. To do that, you must clone my sample GitHub repositories used in this article. You can find them here: repository1 (Spring Boot, H2, Liquibase) and repository2 (Spring Boot, Redis). Then you should only follow my instructions.

Prerequisites

Before we begin, we need to install the JDK version provided by the Leyden project. I installed the macOS version available here. If you need a version for a different operating system, you can find it at the link I included in the introduction to this article. I assume you’re installing this version of Java solely to test Leyden’s functionality. So just extract it somewhere, and during the session, set the JAVA_HOME environment variable to its location. Here’s how it looks for me:

$ export JAVA_HOME=/opt/addons/jdk/Contents/Home
$ java --version
openjdk 26-leydenpremain 2026-03-17
OpenJDK Runtime Environment (build 26-leydenpremain+1-24)
OpenJDK 64-Bit Server VM (build 26-leydenpremain+1-24, mixed mode, sharing)

ShellSession

In the same window, let’s also check the version of Maven. It should also see the 26-leydenpremain version of Java.

$ mvn --version
Apache Maven 3.9.12 (848fbb4bf2d427b72bdb2471c22fced7ebd9a7a1)
Maven home: /opt/homebrew/Cellar/maven/3.9.12/libexec
Java version: 26-leydenpremain, vendor: Oracle Corporation, runtime: /opt/addons/jdk/Contents/Home
Default locale: en_PL, platform encoding: UTF-8
OS name: "mac os x", version: "15.7.4", arch: "aarch64", family: "mac"

ShellSession

Leyden with Spring Boot Application

Spring Boot with an in-memory database and Liquibase

Let’s begin with the spring-boot-tips repository. This application starts with the embedded, in-memory H2 database and connects to it immediately upon launch. Then it uses Liquibase to initialize the database schema. There are also some additional dependencies, such as Spring Data JPA or Springdoc OpenAPI.

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-validation</artifactId>
</dependency>
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-liquibase</artifactId>
</dependency>
<dependency>
  <groupId>org.springdoc</groupId>
  <artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
  <version>3.0.2</version>
</dependency>
<dependency>
  <groupId>com.h2database</groupId>
  <artifactId>h2</artifactId>
  <scope>runtime</scope>
</dependency>

XML

Firstly, go to the application directory and build it with Maven:

mvn clean package -DskipTests

ShellSession

Then you can start it with Java in the standard way just to check the app’s startup time. You can see my startup time below. It takes 3 seconds to start the app and initialize an in-memory database with Liquibase.

leyden-spring-boot-aot-cache

Now, let’s start the same application with the -XX:AOTCacheOutput flag. This flag tells the JVM to generate and save an Ahead-Of-Time (AOT) compilation cache to a file during execution. It should contain the desired name of the output file.

java -XX:AOTCacheOutput=spring-boot-tips.aot -jar target/spring-boot-tips-1.3-SNAPSHOT.jar

ShellSession

After you stop the app, its AOT cache should be written to a file. You should see something similar to what I see in the logs.

Next, to run the application using the AOT cache previously saved in a file, use the -XX:AOTCache parameter specifying the file’s location on disk.

java -XX:AOTCache=spring-boot-tips.aot -jar target/spring-boot-tips-1.3-SNAPSHOT.jar

ShellSession

The app launches about a second faster than before. This example may not be entirely representative, since an in-memory database is also being launched here.

leyden-spring-boot-aot-cache-start

Improve performance with Spring AOT Cache

The result isn’t bad, but actually it’s not very impressive. However, we can still improve it significantly by using Spring Boot’s AOT cache support. Compared to the previous approach, we must perform a training run on our application with its extracted form.

$ java -Djarmode=tools -jar target/spring-boot-tips-1.3-SNAPSHOT.jar \
    extract --destination application

ShellSession

The command above extracts the main jar to the application directory and all libraries to the application/lib directory. The next step is actually the same as in the previous attempt.

$ cd application
$ java -XX:AOTCacheOutput=spring-boot-tips.aot -Dspring.context.exit=onRefresh \
    -jar spring-boot-tips-1.3-SNAPSHOT.jar

ShellSession

Now our app’s startup time looks much more impressive. We’ve gone from about 3 seconds to 0.75 seconds. At this point, I’d like to extend my heartfelt thanks to Sebastien Deleuze for bringing this Spring Boot feature to my attention.

Spring Boot with an external Redis database

Now let’s move on to the sample-spring-redis repository. This application no longer uses the in-memory database or initializes it at startup. Instead, it connects to a running Redis instance. Here’s a list of included Maven dependencies.

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-web</artifactId>
</dependency>

XML

This repository already contains docker-compose.yml file, so you can easily run Redis on Docker with the following command:

docker compose up

ShellSession

Now you can repeat the exact same steps as for the previous app. Convert the app jar to the extracted form and start the app with the –XX:AOTCacheOutput JVM parameter.

$ java -Djarmode=tools -jar target/sample-spring-redis-1.1-SNAPSHOT.jar \
    extract --destination application

$ cd application

$ java -XX:AOTCacheOutput=sample-spring-redis.aot -Dspring.context.exit=onRefresh \
    -jar sample-spring-redis-1.1-SNAPSHOT.jar

ShellSession

It took 1.1 seconds on my laptop to start the sample-spring-redis app. After you stop the app, the AOT cache is saved to the sample-spring-redis.aot file.

Here’s the final comparison. Sample Spring Boot app starts 0.27 seconds with Project Leyden, which is around 4x faster than before (1.1 seconds). Not bad 🙂

Conclusion

My tests with Project Leyden show about a 75% faster startup for the Spring Boot app, which is a solid improvement. Similar results have already been achieved with solutions like CRaC, for example, in Azul’s JVM. Of course, the benefit of Project Leyden is that it can be included as a standard in the OpenJDK distribution. However, in practice, the biggest gains for startups still come from GraalVM and its native-image approach. On the other hand, the Leyden project does not require as long a build time or as many resources as a native build does.