Latest Java Reaches You!

6,860

Premium

1,935 visitors

Home » Blogs » Spring Projects » Spring Boot » Boost Microservices Startup-Spring Boot, CDS & Java Project Leyden

In the fast-evolving landscape of cloud-native and serverless applications especially microservices, runtime efficiency is paramount. Performance requirements might expect some microservices to start and be available without any measurable delays. Due to startup delays inherent in the Java platform, it is difficult to have applications booting with sub-second delays. Spring Boot, a cornerstone of the Java ecosystem, has risen to this challenge by introducing first-class support for Class Data Sharing (CDS) in version 3.3, integrating with the Ahead-of-Time (AOT) cache introduced in Java 24 via Project Leyden.

Java developers face increasing pressure to deliver microservices applications that start quickly, consume minimal memory, and scale efficiently in environments like Kubernetes and serverless platforms. This article explores how these technologies optimize Spring Boot applications, offering practical steps, real-world use cases, and comparisons with alternatives like GraalVM Native Image and CRaC. This post provides a unique, in-depth perspective for developers and architects aiming to supercharge their applications.

I would recommend to refer my Java article ‘Java Runtime Efficiency: Ahead-of-Time (AOT) Compilation with Project Leyden OpenJdk’ on Project Leyden before you go ahead.


The Need for Runtime Efficiency in Java Applications

Java applications have long been celebrated for their robustness and portability but criticized for slow startup times and high memory usage compared to newer languages like Go or Rust. In cloud-native environments, where containers spin up and down rapidly, and serverless functions demand sub-second startup times, these limitations can inflate costs and degrade user experiences. For instance, Kubernetes autoscaling relies on fast pod initialization, while serverless platforms like AWS Lambda charge based on execution time and memory usage.

Spring Boot, with its convention-over-configuration philosophy, simplifies Java development but traditionally inherits the JVM’s startup and memory overhead. Recent advancements, such as CDS and AOT cache support in Spring Boot 3.3 and the upcoming optimizations from Project Leyden, address these challenges head-on, making Spring Boot a compelling choice for modern deployments. This guide dives into these technologies, showing how they reduce startup times, lower memory footprints, and pave the way for scale-to-zero architectures. So, these are very important to consider in microservices architecture.

Before we go further few background –

There are multiple plausible solutions to minimize applications booting with sub-second delays and so optimizing applications for deployment – OpenJDK CRaC (Coordinated Restore at Checkpoint) and GraalVM Native Image, CDS (Class Data Sharing). Spring Boot has built-in support for both of these Java Development Kits.

CRaC addresses the issue of slow JVM startup and “warmup” time. CRaC bypasses the initial startup and warmup phases of the JVM and application by restoring from a pre-optimized state:

CRaC allows you to take a snapshot of a running Java application’s state, including the JVM and its optimized code. This snapshot captures the “warmed-up” state, so when the application is restored from this snapshot, it can start immediately with peak performance. 

How GraalVM improves JIT compilation before AOT:

GraalVM incorporates an advanced JIT compiler, known as the Graal compiler, designed for higher performance and efficiency. The Graal compiler, written in Java, replaces the default HotSpot JVM compiler and applies sophisticated optimization techniques like method inlining, eliminating unused code paths, and speculative optimizations based on runtime profiling. 

AOT Optimizations as third option advanced than CDS:

The “AOT Cache” from OpenJDK Project Leyden is a successor of the old Class Data Sharing (CDS).

Spring Boot 3.3 provides two new features to achieve it: self-extracting executable JAR and Buildpacks CDS support which microservices are already leveraging.


Self-extracting executable JAR

Running the application from an exploded structure is faster and recommended in production.

Spring Boot supports extracting the application jar in a layout (default) which is CDS and AOT Cache friendly. Spring Boot 3.3 has the capability for an executable JAR to self-extract without requiring any external tool, just with the java command.

  •  Libraries are extracted to a lib/ folder.
  • The application jar contains the application classes.
  • Manifest which references the libraries in the lib/ folder

To unpack the executable jar, run following command:

$ java -Djarmode=tools -jar javadevtech-app.jar extract  --destination application

And then in production, you can run the extracted jar:

$ java -jar application/javadevtech-app.jar

Understanding Class Data Sharing (CDS) in Spring Boot

What is CDS?

Class Data Sharing (CDS) is a JVM feature that reduces startup time and memory usage by sharing class metadata across multiple JVM instances. When a Java or microservices application starts, the JVM loads and verifies class files, a process that can be time-consuming, especially for large applications like those built with Spring Boot. CDS mitigates this by creating an archive of pre-processed class metadata during a “training run,” which subsequent JVM instances can reuse, bypassing redundant loading and verification steps.

CDS Evolution from Java 9 to Java 25

  • Java 9: Introduced basic CDS functionality for the core JDK.
  • Java 10–13: Expanded support to include application classes.
  • Java 14+: Added AppCDS and dynamic archive generation.
  • Java 17: Improved tooling for Spring Boot and Springio users.
  • Java 24 and 25: Streamlined AOT Cache and profiling integration as part of Project Leyden.

Spring Boot 3.3’s CDS Support

The Class Data Sharing (CDS), a JVM feature helps reducing the startup time and memory footprint of Java applications. With Spring Boot the minimum requirement is – Java 17+ & Spring Boot 3.3+

Spring Boot 3.3 introduces seamless CDS integration, making it accessible without requiring developers to modify their application code. A key enabler is the -Dspring.context.exit=onRefresh property, which allows Spring Boot to exit after initializing the application context during a training run, creating a CDS archive without running the full application. This archive, typically a .jsa file, is then used in production to accelerate startup and reduce memory usage.

Self-extracting executable JAR + Class Data Sharing (CDS)

To use CDS, training run has to be performed on extracted form of application resulting application.jsa archive file.

$ java -Djarmode=tools -jar javadevtech-app.jar extract --destination application
$ cd application
$ java -XX:ArchiveClassesAtExit=application.jsa -Dspring.context.exit=onRefresh -jar javadevtech-app.jar

The archive can be reused as long as the application is not updated.

Using the archive when starting the application.

$ java -XX:SharedArchiveFile=application.jsa -jar javadevtech-app.jar

Followings are few additional points to consider.

CDS and Spring AOT Activation Support in Buildpacks

Note – The terms Spring AOT and Java AOT Cache in Project Leyden are different.

Above so far we have seen a lot of manual steps. Spring Boot’s integration with Buildpacks simplifies CDS adoption in containerized environments for microservices. Buildpacks automate the creation of container images, embedding CDS archives to optimize startup performance. This is particularly valuable for cloud-native deployments, where manual configuration can be error-prone and time-consuming.

How Buildpacks Enable CDS

Buildpacks for Spring Boot, starting with version 3.3, include built-in support for generating CDS archives during the image build process. When you build a container image using the pack CLI or a CI/CD pipeline, the Buildpack detects the Spring Boot application and its JDK version, automatically triggering a training run to create a CDS archive. This archive is stored in the image’s filesystem (e.g., /app.jsa) and configured for use when the container starts.

With maven it can be enabled in following way:

<plugin>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-maven-plugin</artifactId>
	<configuration>
		<image>
			<env>
				<BP_JVM_CDS_ENABLED>true</BP_JVM_CDS_ENABLED>
			</env>
		</image>
	</configuration>
</plugin>

To avoid the interaction with database during the training you can configure your application as per this document. OR you can training run with the CDS_TRAINING_JAVA_TOOL_OPTIONS environment variable.

Spring AOT Activation Support

Spring Boot’s AOT engine, introduced in earlier versions for GraalVM Native Image compatibility. Buildpacks integrate with Spring’s AOT processing to pre-generate application context metadata, which complements CDS by reducing runtime initialization overhead. The Buildpack triggers AOT processing alongside CDS archive creation, ensuring that both class metadata and application context data are optimized.

It can be triggered with the BP_SPRING_AOT_ENABLED environment variable by keeping following constraints –

  • Enable Spring AOT in your Maven or Gradle build.
  • Potentially configure Spring AOT to use the Spring profile that will be used in the deployment environment.
  • CDS_TRAINING_JAVA_TOOL_OPTIONS and BP_SPRING_AOT_ENABLED can’t be combined.

Benefits of Buildpacks Integration

  • Automation: Eliminates manual steps for CDS archive creation and Spring AOT processing, reducing configuration errors.
  • Portability: Produces container images that work across Kubernetes, Docker, and serverless platforms.
  • Consistency: Ensures the CDS archive and AOT config are generated with the same JDK and classpath used in production.
  • Scalability: Simplifies CI/CD integration, allowing teams to deploy optimized images at scale.

Considerations

  • Build Time: Generating CDS archives and AOT caches increases build time, typically by 10-30 seconds, depending on application complexity.
  • Image Size: The CDS archive adds 10-50 MB to the container image. Use compression (e.g., UPX or gzip) if storage is a concern.
  • JDK Compatibility: Ensure the Buildpack uses a JDK version that supports CDS (Java 5+) and, for AOT cache, Java 24 or later.

For above approaches, let’s take a look at the comparison in data points observed in Spring MVC Tomcat application and Petclinic for startup and memory optimization.


Project Leyden: The Future of Java Performance

What is Project Leyden?

Project Leyden, initiated by Oracle’s HotSpot and Core Libraries Groups in 2022, aims to revolutionize Java application performance by focusing on three key metrics: startup time, time to peak performance, and memory footprint. Unlike GraalVM Native Image, which imposes a closed-world assumption, Project Leyden seeks to preserve Java’s dynamic features (e.g., reflection, dynamic class loading) while delivering ahead-of-time (AOT) optimizations.

The first major milestone, JEP 483 (Ahead-of-Time Class Loading & Linking), was integrated into Java 24, introducing an AOT cache that builds on CDS. This cache pre-processes not only class metadata but also linking information, further reducing startup overhead. Spring Boot’s CDS and AOT support is designed with Project Leyden in mind, ensuring compatibility with these advancements.

JEP 483 and the AOT Cache

JEP 483 enhances CDS by introducing an AOT cache that stores pre-linked class data, reducing the work performed during JVM startup. Unlike traditional CDS, which requires identical JDK and classpath configurations between training and production, the AOT cache offers greater flexibility, supporting multiple application versions and configurations. Sébastien Deleuze’s demo showed how the AOT cache, combined with Spring Boot’s CDS support, delivers significant startup time improvements without compromising Java’s dynamic nature.


Optimizing Spring Boot Applications with AOT Cache

What is the AOT Cache?

The AOT cache, introduced in Java 24 via JEP 483, extends CDS by pre-computing class loading and linking steps, storing the results in a reusable cache. This cache includes not only class metadata but also resolved references, method tables, and other runtime structures, significantly reducing startup overhead. For Spring Boot applications, the AOT cache integrates seamlessly with the framework’s context initialization, leveraging Spring’s AOT engine to pre-generate bean definitions and wiring.

Implementing AOT Cache in Spring Boot

Minimum requirement is – Java 24+ & Spring Boot 3.3+

Please check my Java article ‘Java Runtime Efficiency: Ahead-of-Time (AOT) Compilation with Project Leyden OpenJdk’ on Project Leyden for more detail.

To use the AOT cache with a Spring Boot application or microservices, you need Java 24 (early-access build or later) and Spring Boot 3.3 or higher. The process mirrors CDS archive creation but uses additional JVM flags to enable AOT optimizations.

To use AOT Cache, training run has to be performed on extracted form of application.

JDK 24: Class Loading & Linking

The first step is the training run which generates a configuration file app.aotconf.

The second step is to build an AOT cache file file app.aot from the configuration.

$ java -Djarmode=tools -jar javadevtech-app.jar extract --destination application
$ cd application
$ java -XX:AOTMode=record -XX:AOTConfiguration=app.aotconf -Dspring.context.exit=onRefresh -jar javadevtech-app.jar
$ java -XX:AOTMode=create -XX:AOTConfiguration=app.aotconf -XX:AOTCache=app.aot -jar javadevtech-app.jar

app.aot cache file can be reused as long as the application is not updated.

The intermediate app.aotconf file is no longer needed and can be safely deleted.

JDK 25: Command-Line Ergonomics

JDK 25 simplifies AOT usage by allowing a single-step cache creation using the -XX:AOTCacheOutput option:

$ java -Djarmode=tools -jar javadevtech-app.jar extract --destination application
$ cd application	
$ java -XX:AOTCacheOutput=app.aot -cp javadevtech-app.jar

Running the app by using the AOT cache.

$ java -XX:AOTCache=app.aot -jar javadevtech-app.jar

Now it is approximately 3x faster startup on Spring Boot applications with Project Leyden and 4x faster startup when combining Project Leyden and Spring AOT. let’s take a look at the comparison in data points observed in Spring MVC Tomcat application and Petclinic.

Benefits of AOT Cache

  • Faster Startup: The AOT cache reduces startup time by 50-70% compared to 30-50% with traditional CDS, as demonstrated in the Spring PetClinic demo (~1.3 seconds vs. ~3.5 seconds without optimization).
  • Lower Memory Usage: Pre-linked data reduces runtime memory allocation, typically by 20-30%. Smaller container images (by removing the CDS archive of the JDK to keep only the application one).
  • Flexibility: The AOT cache supports dynamic classpath changes, unlike traditional CDS, making it suitable for complex Spring Boot applications.
  • Serverless Compatibility: The reduced startup time enables scale-to-zero architectures, where applications start and stop frequently.
  • Ahead-Of-Time warmup to have better performance after startup and reach peak performance faster.

Challenges

  • Early Access: The AOT cache is available in Java 24 early-access builds, so production use requires rigorous testing.
  • Increased Build Complexity: AOT cache generation requires Java 24 and may increase build times slightly compared to CDS alone.
  • Compatibility: Ensure all libraries in your Spring Boot application are compatible with Java 24’s AOT features.

Troubleshooting Tips

  • Archive Mismatch: Ensure identical JDK and classpath between training and production. Use -Djarmode=tools for consistent classpaths.
  • AOT Cache Compatibility: Verify that libraries support Java 24’s AOT features, as some may require updates.
  • Performance Monitoring: Use tools like VisualVM or JFR to measure startup time and memory improvements.

Anticipating Project Leyden’s Future Enhancements

Project Leyden’s roadmap includes several JEPs that promise to further enhance Spring Boot performance:

  • Ahead-of-Time Method Profiling: Optimizes method inlining and JIT compilation by pre-computing profiles during training runs.
  • Command Line Ergonomics: Simplifies AOT cache usage with user-friendly flags and tools.
  • AOT Code Compilation: Pre-compiles Java bytecode into native code, reducing time to peak performance.

These enhancements will make Project Leyden a game-changer for serverless and scale-to-zero architectures, where applications must start instantly and shut down cleanly. Unlike GraalVM Native Image, which restricts dynamic features, Project Leyden’s weaker constraints ensure compatibility with Spring Boot’s flexible dependency injection and configuration mechanisms.


Comparing CDS, AOT Cache, and Alternatives

FeatureCDSAOT Cache (Project Leyden)GraalVM Native ImageCRaC
Startup TimeModerate (~30-50%)Significant (~50-70%)Excellent (~90%+)Excellent (~90%+)
Memory FootprintReduced (~10-20%)Further reduced (~20-30%)MinimalModerate
ConstraintsMinimal (dynamic features)Minimal (improved flexibility)Strict (closed-world)Checkpoint support needed
Use CaseGeneral-purpose, easy adoptionCloud-native, serverlessServerless, small appsLong-running apps
MaturityStable (Java 5+)Early access (Java 24)MatureExperimental

CDS and AOT Cache vs. GraalVM Native Image

GraalVM Native Image compiles Java applications into native executables, offering sub-second startup times but restricting dynamic features like reflection. CDS and AOT cache, by contrast, support Spring Boot’s dynamic nature, making them suitable for complex applications with extensive dependency injection.

CDS and AOT Cache vs. CRaC

CRaC snapshots a running JVM’s state for near-instantaneous restarts but requires specialized JVM support. CDS and AOT cache are more broadly compatible and easier to integrate with existing Spring Boot workflows.

Choosing the Right Approach

  • Use CDS for general-purpose applications with minimal setup.
  • Use AOT Cache for cloud-native and serverless deployments needing maximum startup and memory efficiency.
  • Use GraalVM Native Image for small, self-contained applications.
  • Use CRaC for long-running services with checkpoint-compatible JVMs.

Real-World Use Cases and Benefits

Kubernetes Autoscaling

A retail microservices platform on Kubernetes can use CDS and AOT cache to reduce pod startup from 5 seconds to 1.5 seconds, improving scalability and reducing cloud costs. For 100 pods, this can save thousands of dollars monthly on AWS EKS.

Serverless Functions

A Spring Boot API function on AWS Lambda can leverage AOT cache to cut cold start time from 4 seconds to 1 second, lowering costs and improving user experience. Future Project Leyden enhancements could enable true scale-to-zero.

Spring PetClinic Benchmark

The Spring PetClinic demo reduced startup time from ~3.5 seconds to ~1.3 seconds using CDS and AOT cache, with a ~20% memory reduction. These gains are critical for real-world applications like e-commerce or financial systems.


Challenges and Considerations

  • Image Size: CDS and AOT cache archives increase container image size by 10-50 MB. Use compression if needed.
  • Classpath Consistency: Ensure identical JDK and classpath for CDS and AOT cache.
  • Early Access Risks: Test Java 24’s AOT cache thoroughly before production use.
  • Dynamic Features: Verify library compatibility with AOT cache, especially for heavy reflection usage.

Future Outlook and Community Involvement

Project Leyden is a community-driven effort, and developers can contribute via the leyden-dev mailing list. The Spring team’s collaboration with the Java Platform team ensures future Spring Boot releases will leverage Project Leyden’s advancements. Upcoming talks at Spring I/O 2025 will provide further insights. Developers can experiment with Java 24 and Spring Boot 3.3 to prepare for these optimizations.


Conclusion

Spring Boot’s CDS and AOT support, combined with Project Leyden’s vision, empower developers to build efficient, cloud-native applications or microservices. By integrating these technologies with Buildpacks, teams can automate optimization and deploy at scale. Start experimenting with CDS and AOT cache today, and join us for Project Leyden updates to shape the future of Java performance.

Comments

Leave a Reply


Discover more from JavaDevTech platform

Subscribe to get the latest posts sent to your email.

Support Us By Donating!

Choose an amount

$5.00
$15.00
$100.00

OR Enter custom amount

$

Your contribution is APPRECIATED!

DONATE

Discover more from LEARN Java Development & Technologies

Subscribe now to keep reading and get access to the full archive.

Continue reading