Visit Support

Coordinated Restore at Checkpoint Usage Guidelines

Your application may be ready for CRaC out-of-the-box! The simplest way is trying to generate a checkpoint. When you meet a CheckpointException, (that describes the problematic state in the application), or if you want to have more control, check the "Implementing the CRaC Resource" section.

Using CRaC in Your Application

Adding the CRaC API

The library provided by org.crac is designed to provide a smooth CRaC adoption. Add this library to build an application that uses the CRaC API, to be able to run it on Java runtimes with CRaC, or without any implementation.

You can find the library in the Maven Repository.


<dependency> <groupId>org.crac</groupId> <artifactId>crac</artifactId> <version>${crac.version}</version> </dependency>


implementation 'org.crac:crac:1.4.0'


During runtime, org.crac uses reflection to detect the CRaC implementation. When available, all requests to org.crac are passed to the implementation. Otherwise, requests are forwarded to a dummy implementation.

The dummy implementation allows an application to run but not to use CRaC:

  • Resources can be registered for notification.

  • Checkpoint request fails with an exception.

Implementing the CRaC Resource

To use the API, you need to identify all classes in your code that are considered "resources": classes that must be notified when a checkpoint is about to be made and when a restore has happened. The API provides an eponymous interface, Resource, which must be implemented for the identified classes. There are only two methods, beforeCheckpoint() and afterRestore() which are used as callbacks by the JVM.

package; import org.crac.Context; import org.crac.Core; import org.crac.Resource; public class MyClass implements Resource { public MyClass() { Core.getGlobalContext().register(this); } @Override public void beforeCheckpoint(Context<? extends Resource> context) { /* ... */ } @Override public void afterRestore(Context<? extends Resource> context) { /* ... */ } }

The CRaC JavaDoc is available here.

Example use case:

  • If a class reads configuration from a file, the file must be closed in the beforeCheckpoint() method.

  • In the afterRestore() method, the file can be opened again to check configuration updates.

The same applies to network connections, and you can also use the methods to deal with a sudden change in the system clock, which might impact things like cache timeouts.

All Resources in the application must be registered with the JVM, which can be achieved by obtaining a CRaC Context and using the register() method. Although you can create your own Context, the simplest way is to use the global Context obtained via the Core class’s static getGlobalContext() method.

It’s important to register the Resources in the right order because this order is used to call the beforeCheckpoint methods. However, the afterRestore methods are called in the opposite order. This approach simplifies things if there is a particular sequence in which things need to be prepared for a checkpoint; when restoring, there is a predictable inverse sequence.

The API also provides the Core.checkpointRestore() method to create a checkpoint programmatically within your application. You can add this call in the flow of your program, where you want the checkpoint to be created. The method will return when the restore has been completed. This call can also be done with jcmd <PID or your_app.jar> JDK.checkpoint at any moment during the lifetime of your application, as described in Generating a Checkpoint further on this page.

Running an Application With CRaC

Currently, the full CRaC functionality is only available on Linux/x64 and Linux/Arm64, in version 17, 21, and 22 of Azul Zulu Builds of OpenJDK. This means, for now, you can run an application with CRaC on any system thanks to the dependency, but only on the specified OS systems the CRaC functionality in the JVM will work.

As you can see in the January 2024 Release Notes, downloads are also available for Windows and macOS of Zulu with CRaC support, but only for development purposes. With these runtimes you are able to simulate the CRaC functionality. When you request a checkpoint, it is created and immediately restored without dumping the checkpoint to disk. This enables you to develop and test the CRaC functionality on these platforms, so you can deploy your application with confidence on Linux.

Some VMs, like Parallels, cannot run foreign CPU instructions, and you need a build matching your CPU. Some other virtualization environments, like WSL, do not provide a complete feature set of Linux kernel, limiting the CRaC functionality in the current version.

Detailed instructions per type of environment:

Running CRaC on Linux

Version 17, 21, and 22 of Azul Zulu Builds of OpenJDK, with CRaC functionality, are available as of the release of April 2023. Only the bundles with -crac- in the name, have the integrated CRaC functionality.

Download a Runtime

On the download section of the Azul website, you can use the "Java Package" > "JDK CRaC" filter.

The JDK archive should be extracted with sudo.
$ sudo tar zxf <jdk>.tar.gz

Generating a Checkpoint

Start the JVM with an additional flag -XX:CRaCCheckpointTo so it’s prepared to create a checkpoint:

java -XX:CRaCCheckpointTo=$HOME/crac-image/ -jar my_app.jar
This eventually generates a set of files in the given directory, which cumulative size will be roughly the size of the JVM resident memory.

Then you can trigger the checkpoint from outside the JVM, using jcmd with JDK.checkpoint:

jcmd my_app.jar JDK.checkpoint

Using a Checkpoint

When a checkpoint is available, you can (re)start your application and restore from the image:

java -XX:CRaCRestoreFrom=$HOME/crac-files/

Running CRaC in a Container (Docker)

Creating a Docker Image

  1. You need an application in a runnable JAR file.

  2. Check which Zulu Docker Image version you want to use on Docker Hub.

  3. Create a Dockerfile, based on the following minimum file (using Zulu 21 in this example):

    FROM azul/zulu-openjdk:21-jdk-crac-latest COPY build/libs/my_app.jar /opt/app/my_app.jar
  4. Build the Docker image with:

    docker build -t my_app_on_crac .

Starting an Application in a Docker Container

  1. Run a Docker container with:

    docker run -it --cap-add=CHECKPOINT_RESTORE --cap-add=SYS_PTRACE --rm --name my_app_on_crac \ -v $PWD/crac-files:/opt/crac-files my_app_on_crac \ java -XX:CRaCCheckpointTo=/opt/crac-files -jar /opt/app/my_app.jar
In order to restore without additional capabilities (see below), you should make java to be PID 1 process.
  1. Leave the shell window open and the application running.

Creating the Checkpoint

  1. Open another shell window.

  2. In this window run:

    docker exec my_app_on_crac jcmd PID-OR-NAME JDK.checkpoint
    You can find PID or NAME to provide to jcmd by executing just jcmd in the container.
  3. If everything is ok, you see that in the first shell window the checkpoint was created and your application was closed.

Creating a Docker Image with Checkpoint

  1. Create a Dockerfile with the checkpoint:

    FROM my_app_on_crac COPY crac-files /opt/crac-files
  2. Build the Docker image with

    docker build -t my_app_on_crac_restore .

Run the Docker Container From the Checkpoint

  1. Run:

    docker run -it --rm --cap-add=SYS_RESOURCE my_app_on_crac_restore java \ -XX:CRaCRestoreFrom=/opt/crac-files
  2. Your application now starts much faster from the saved checkpoint.

A restore in an unprivileged container (without the SYS_RESOURCE capability) might succeed but we have identified some issues with stability related to the brk syscall; therefore it is strongly recommended to use this additional capability. NOTE: You can run the Docker container also on macOS or Windows, as long as the machine you are running it on has a x64 cpu architecture (Intel/AMD).

Running CRaC on Windows or macOS

You can test your CRaC application on Windows or macOS with one of the following approaches:

  • Run your application in a containerized Linux system, e.g. following the Docker approach described above. For instance, on macOS you can use Docker, Podman, Parallels, VirtualBox,…​

  • Use an Azul Zulu Build of OpenJDK with CRaC support for development purposes, available for Windows and macOS. These provide a simulated checkpoint/restore mechanism to be used for development and testing.

Example Code

Within the CRaC project on GitHub, a fully documented "Step-by-step CRaC support for a Jetty app" is provided.