Pierre Renard
Cloud technologies addict. Pierre enjoys making awesome cloud-based solutions.
Accelerate your Lambda functions with SnapStart
The cloud is a wonderful enabler to quickly create deploy and run a new application. In the early age, the cloud was only provided hosting services and then quickly provides a bunch of services. Now, AWS provides more than hundred services. One of them is Lambda. AWS Lambda let you run your code to the cloud without the need to manage the underlying infrastructure. It allows developers to focus more on the code. The drawback of lambdas was that not all programming languages were “performant” to run on this service. It was the case for Java. The lambda execution could take several seconds to initialize even before executing the code. Now, AWS provides several features to speed the process. One of them was recently announced; the Lambda SnapStart!
Table of Contents
What “Cold start” means?
The “Cold start” defines the first invocation of a lambda. During this phase called the “init phase”, the lambda does:
- Start all extensions;
- Bootstrap the runtime;
- Run the code outside the handler.
The Lambda is now initialized and the code defined in the handler can be run.
After the first invocation, the underlying lambda container will be idle for around 15 minutes. Next invocations will not run the init phase and, then, directly run the handler.
The cold start duration may vary from less than a second to several seconds. It impacts for sure the user’s experience. Moreover, not all runtimes are equals with the cold start duration. Runtimes like Java have a lot of tasks to do in the init phase to have the lambda container running. It was mainly for it that we recommend using instead the Node or Python runtime which have a very little init phase duration.
But now AWS came with a new feature called AWS Lambda SnapStart!
AWS Lambda SnapStart; The game changer
Lambda SnapStart improves startup performance up to 10x, in most cases, with no changes to your function code. This optimization is based on the mitigation of the “cold start”.
In the scope of our blog post, we setup a proof of concept to test this new feature powered by the Serverless framework and the AWS cloud. Let’s deep dive into the subject!
Prerequisites
To deploy a Java application to test the new SnapStart feature, we must install some applications and packages. Here is the list of software’s versions used for the proof of concept:
- Java 11;
- Maven 3.6;
- Node 19.4.0 with NPM 9.2.0;
- Serverless 3.26.0.
You must also have an AWS account with an AWS profile preconfigured.
Setup
To show you the benefit of using the SnapStart feature, we will deploy one lambda with a standard Java application that output “Hello World” when called. Thanks to the Serverless Framework, we will quickly deploy a lambda function to AWS.
For the use case, we will use the “getting-started” project provided by the framework. By running the command serverless create --template aws-java-maven
, it will download a blueprint for a standard Java application. Let’s bootstrap the application.
1
2
3
4
5
6
$ serverless create --template aws-java-maven
[v] Project successfully created in "./" from "aws-java-maven" template (2s)
Please update the "service" property in serverless.yml with your service name
We can see that the project has been successfully setup.
1
2
3
4
5
6
7
8
9
10
11
$ tree my-project/
.
├── src/main/
│ ├── java/com/serverless/
│ │ ├── ApiGatewayResponse.java
│ │ ├── Handler.java
│ │ ├── Response.java
├── resources/
│ ├── log4j2.xml
├── pom.xml
├── serverless.yml
Let’s build the Java application with maven:
1
2
3
4
5
6
7
8
9
10
11
12
13
$ mvn clean install
[INFO] Scanning for projects...
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building hello dev
[INFO] ------------------------------------------------------------------------
...
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 24.225 s
[INFO] Finished at: 2023-01-16T11:53:37+01:00
[INFO] ------------------------------------------------------------------------
We can see at the root level of the project a file named serverless.yml
. This file describes all the resources that we want to deploy to the cloud. Let’s clean and modify the file:
- Modify the
runtime
parameter tojava11
- Add the
profile
parameter and, as value, your preconfigured AWS profile above.
The new version of the serverless.yml
should looks like that:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# Welcome to Serverless!
service: lambda-snapstart-poc
frameworkVersion: '3'
provider:
name: aws
runtime: java11
stage: dev
region: eu-west-1
profile: my-profile
package:
artifact: target/hello-dev.jar
functions:
hello:
handler: com.serverless.Handler
Let’s deploy!
1
2
3
4
5
6
7
8
9
10
11
$ serverless deploy --aws-profile my-profile
Running "serverless" from node_modules
Deploying lambda-snapstart-poc to stage dev (eu-west-1)
✔ serverless-better-credentials: credentials resolved from config sso profile: cli --aws-profile (my-profile)
✔ Service deployed to stack lambda-snapstart-poc-dev (155s)
functions:
hello: lambda-snapstart-poc-dev-hello (3.9 MB)
Perfect, the lambda was correctly deployed to the AWS account.
We can see in the lamda console, under the configuration panel, that the SnapStart features is not enabled.
Let’s go to the test panel to test our lambda. Since it is never started before, we expect to have a “cold” start.
Indeed, we can see that our lambda function in Java takes almost 2 seconds for the init phase. Let’s run again the lambda.
We can see that we don’t have any init phase anymore. It is because the lambda container is “hot” and idle.
Let’s activate the new feature called AWS Lambda SnapStart. To enable the feature, you must modify the serverless.yml
and add the snapStart: true
property in your lambda function definition.
1
2
3
4
functions:
hello:
handler: com.serverless.Handler
snapStart: true
Run the serverless deploy
again to enable the Snapstart. We can see that the SnapStart is now enabled.
Now, run the test again.
We can see that we have now a restore duration instead of an init duration and it is about 10x times less than the init duration!
Results
We have computed all figures into a table. What we can see is that the Cold start is 10x times longer compared to the restore time with AWS Lambda SnapStart activated. We can also notice that the duration of the lambda is slightly lower with the SnapStart feature enabled.
According to the AWS documentation, there is no additional cost for the AWS Lambda SnapStart. However, if we compare the billed duration, we can see that we are charge for the restore time duration but not for the init duration of the “cold” lambda. In fact, duration charges apply to code that runs initialization code that’s declared outside of the handler, the time it takes for the runtime (JVM) to load, and any code that runs in a runtime hook.
Considerations
With the SnapStart feature, you must know how it works and adapt your code if needed.
Uniqueness
If your code generates unique IDs, secrets, or anything that’s used to generate random data, you must adapt your code to ensure the randomness of your data generated.
Network connections
If you enable network connection outside your handler, you have to validate and, if needed, re-establish the connection.
Temporary data
Cached data during the init phase as well must be refresh including ephemeral data like passwords or timestamps.
We recommend the GitHub project maintained by AWS called AWS Lambda SnapStart Bug Scanner. It helps to inspect lambda functions against potential bugs unique to AWS Lambda SnapStart environment. In addition, we suggest following the Best practices for working with Lambda SnapStart.
Limitations
For the moment AWS Lambda SnapStart is only available with the Java 11 runtime. We have no doubt that the feature will be available for other runtime in the future.
In addition, AWS Lambda SnapStart is not compatible with:
- Provisioned concurrency;
- ARM64 architecture;
- The Lambda Extensions API;
- Amazon EFS;
- Amazon X-Ray;
- Ephemeral storage greater than 512 Mb;
- Unpublished Lambda version ($LATEST). The SnapStart feature can be used only on versioned lambda function and aliases.
Conclusion
Before this feature, the “cold” start for lambdas could takes several seconds. Now, for those lambdas, it is a small revolution! It speeds up our “cold” lambdas up to 10x times at no price.