# 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:

1. extensions can produce a list of classes (using the `io.quarkus.deployment.builditem.PreloadClassBuildItem` build item)

2. 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

### Disable preloading

You can disable the preloading of classes using:

    quarkus.snapstart.preload-classes=false

### Skipping class initialization

By default, when the classes are preloaded, they are also initialized, meaning it also resolves the dependent classes. You can disable this behavior using:

    quarkus.snapstart.initialize-classes=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:

1. initialize the client in a `static` block, which, thanks to class preloading will be executed before the snapshot

2. 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.

## TieredCompilation

It is also recommended to use tiered compilation when using SnapStart. To achieve this, set the `JAVA_TOOL_OPTIONS` environment property to `-XX:+TieredCompilation -XX:TieredStopAtLevel=1`.

| `TieredCompilation` can also be interesting for regular Lambda functions.