AWS Lambda SnapStart Configuration
SnapStart is a snapshotting and restore mechanism reducing drastically the cold startup time of Java functions on AWS. This document explains the various settings you can use to leverage this feature. It is not a reference documentation on SnapStart, and it will not cover how SnapStart works in details.
This feature is only available on AWS Lambda, and not in all regions. Please check the AWS documentation to verify the eligibility of your AWS region. |
Enabling / Disabling SnapStart Optimizations
If you use the Quarkus AWS Lambda extension, SnapStart optimizations are automatically enabled. However, you can enable/disable it explicitly using:
quarkus.snapstart.enable=true|false
It does not enable/disable SnapStart for your function, only the Quarkus optimizations. |
Class Preloading
Classloading has a huge impact on your function execution time. This optimization allows preloading classes during the snapshotting process of SnapStart.
The classes to preload are listed in two places:
-
extensions can produce a list of classes (using the
io.quarkus.deployment.builditem.PreloadClassBuildItem
build item) -
you can add a
src/main/resources/META-INF/quarkus-preload-classes.txt
file listing the classes to preload, such as:
com.amazonaws.services.lambda.runtime.LambdaRuntimeInternal
com.fasterxml.jackson.annotation.JsonAlias
com.fasterxml.jackson.annotation.JsonFormat$Feature
com.fasterxml.jackson.core.exc.InputCoercionException
com.fasterxml.jackson.core.exc.StreamWriteException
com.fasterxml.jackson.core.io.ContentReference
com.fasterxml.jackson.core.io.IOContext
com.fasterxml.jackson.core.io.JsonEOFException
com.fasterxml.jackson.core.io.MergedStream
com.fasterxml.jackson.core.io.NumberInput
com.fasterxml.jackson.core.io.NumberOutput
com.fasterxml.jackson.core.io.UTF32Reader
com.fasterxml.jackson.core.json.ByteSourceJsonBootstrapper
com.fasterxml.jackson.core.json.JsonReadContext
com.fasterxml.jackson.core.json.JsonWriteContext
com.fasterxml.jackson.core.json.UTF8StreamJsonParser
com.fasterxml.jackson.core.JsonEncoding
com.fasterxml.jackson.core.JsonGenerationException
com.fasterxml.jackson.core.JsonLocation
com.fasterxml.jackson.core.JsonStreamContext
com.fasterxml.jackson.core.JsonToken
...
The format is simple: one class per line.
Computing the class list
That step is particularly not user-friendly. We plan to improve it. |
To compute the list of classes, we recommend deploying your function and setting the JAVA_TOOL_OPTIONS
environment variable to -verbose:class
.
Then execute your function and retrieve the log (in CloudWatch).
You should be able to extract the class names using sed/awk or any text editor.
Application class list
By default, Quarkus generates the class list of the classes included in your application (including the classes generated by Quarkus).
So, you do not have to repeat them in the quarkus-preload-classes.txt
file.
You can disable this feature using:
quarkus.snapstart.generate-application-class-list=false
Client Priming
Client priming is a technique that allows initializing a client during the snapshotting process, so it’s already fully functional during the application runtime.
There are two ways to achieve priming:
-
initialize the client in a
static
block, which, thanks to class preloading will be executed before the snapshot -
register a CRaC Resource doing the initialization
(1) can be achieved as follows:
@ApplicationScoped
public class HeroRepository {
private static final DynamoDbClient client;
static {
client = DynamoDbClient.builder()
.region(Region.US_EAST_2)
.credentialsProvider(DefaultCredentialsProvider.create())
.build();
client.describeEndpoints();
}
// ...
}
Implementing priming using a static block may prevent the native compilation of your application. Client initialization may start threads or open connections which are not compatible with the native compilation if the class is initialized at build time. |
The next section covers (2).
Resource registration
SnapStart uses the CRaC API to allow the application to execute custom code before the snapshotting or during the restoration.
While it’s the CRaC API, SnapStart is not CRaC and can do things that would not work with others CRaC implementations. |
package org.acme.hello;
import io.quarkus.runtime.Startup;
import org.crac.Context;
import org.crac.Core;
import org.crac.Resource;
import org.jboss.logging.Logger;
import jakarta.annotation.PostConstruct;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.inject.Inject;
@Startup
@ApplicationScoped
public class HelloPriming implements Resource {
@Inject
Logger logger;
@PostConstruct
void init() {
// Important - register the resource
Core.getGlobalContext().register(this);
}
@Override
public void beforeCheckpoint(Context<? extends Resource> context) throws Exception {
logger.info("before checkout hook");
// initialize your client here.
}
@Override
public void afterRestore(Context<? extends Resource> context) throws Exception {
logger.info("after checkout hook");
// if there is anything to do during the restoration, do it here.
}
}
Restoration is limited to 2 seconds. |