This was written by Michele Ricciardi, Specialist Solutions Architect, DevAx.
AWS Lambda SnapStart enables customers to reduce cold starts by caching an encrypted snapshot of an initiated Lambda function, and reusing that snapshot for subsequent invocations.
This blog post describes in more detail how to enable SnapStart with different infrastructure as code tooling: AWS Serverless Application Model (AWS SAM), AWS CloudFormation, and Terraform. It shows what happens during a Lambda deployment when SnapStart is enabled, as well as best practices to apply in CI/CD pipelines.
Snapstart can significantly reduce the cold start times for Lambda functions written in Java. The example described in the launch blog post reduces the cold start duration from over 6 seconds to less than 200ms.
You activate the SnapStart feature through a Lambda configuration setting. However, there are additional steps to use the SnapStart feature.
SnapStart works in conjunction with Lambda function versions. It initializes the function when you publish a new Lambda function version. Therefore, you must enable Lambda versions to use SnapStart. For more information, read the Lambda Developer Guide.
A Lambda function alias allows you to define a custom pointer, and control which Lambda version it is attached to. While this is optional, creating a Lambda function alias makes the management operations easier. You can change the Lambda version tied to a Lambda alias without modifying the applications using the Lambda function.
Once you have a SnapStart-ready Lambda version, you must change the mechanism that invokes the Lambda function to use a qualified Lambda ARN. This can either invoke the specific Lambda Version directly or invoke the Lambda alias, which points at the correct Lambda version.
If you do not modify the mechanism that invokes the Lambda function, or use an unqualified ARN, you cannot take advantage of the optimizations that SnapStart provides.
UnicornStockBroker is a sample Serverless application. This application is composed of an Amazon API Gateway endpoint, a Java Lambda function, and an Amazon DynamoDB table. Find the CloudFormation template without SnapStart in this GitHub repository.
To enable SnapStart:
UnicornStockBrokerFunctionVersion1: Type: AWS::Lambda::Version Properties: FunctionName: !Ref 'UnicornStockBrokerFunction' UnicornStockBrokerFunctionVersion1 to UnicornStockBrokerFunctionVersion2.UnicornStockBrokerFunctionAliasSnapStart: Type: AWS::Lambda::Alias Properties: Name: SnapStart FunctionName: !Ref 'UnicornStockBrokerFunction' FunctionVersion: !GetAtt 'UnicornStockBrokerFunctionVersion.Version' ServerlessRestApi: Type: AWS::ApiGateway::RestApi Properties: Body: paths: /transactions: post: x-amazon-apigateway-integration: [..] uri: !Sub 'arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${UnicornStockBrokerFunctionAliasSnapStart}/invocations' UnicornStockBrokerFunctionUnicornStockBrokerEventPermissionProd: Type: AWS::Lambda::Permission Properties: [..] FunctionName: !Ref UnicornStockBrokerFunctionAliasSnapStart UnicornStockBrokerFunction: Type: AWS::Lambda::Function Properties: [..] SnapStart: ApplyOn: PublishedVersions After these updates, the CloudFormation template with SnapStart enabled looks like this. You can deploy the sample application and take advantage of SnapStart.
You can find the AWS SAM template without SnapStart here. To enable Lambda SnapStart:
UnicornStockBrokerFunction: Type: AWS::Serverless::Function Properties: [..] AutoPublishAlias: SnapStart UnicornStockBrokerFunction: Type: AWS::Serverless::Function Properties: [..] SnapStart: ApplyOn: PublishedVersions This example uses the AWS::Serverless::Function resource with the AutoPublishAlias property. AWS SAM implicitly creates an Amazon API Gateway with the correct permissions and configuration to invoke the Lambda function using the declared Lambda alias.
You can see the modified AWS SAM template here. You can deploy the sample application with AWS SAM and take advantage of SnapStart.
You can find the Terraform template without SnapStart here. To enable Lambda SnapStart using Terraform by HashiCorp:
aws\_lambda\_function resource: resource "aws\_lambda\_function" "UnicornStockBrokerFunction" { [...] publish = true} resource "aws\_lambda\_alias" "UnicornStockBrokerFunction\_SnapStartAlias" { name = "SnapStart" description = "Alias for SnapStart" function\_name = aws\_lambda\_function.UnicornStockBrokerFunction.function\_name function\_version = aws\_lambda\_function.UnicornStockBrokerFunction.version} SnapshotFunction:resource "aws\_api\_gateway\_integration" "createproduct-lambda" { [...] uri = aws\_lambda\_alias.UnicornStockBrokerFunction\_SnapStartAlias.invoke\_arn} uri on the aws\_lambda\_permission to allow API Gateway to invoke the specified Lambda alias: resource "aws\_lambda\_permission" "apigw-CreateProductHandler" { [...] qualifier = aws\_lambda\_alias.UnicornStockBrokerFunction\_SnapStartAlias.name} aws\_lambda\_function resource: resource "aws\_lambda\_function" "UnicornStockBrokerFunction" { [...] snap\_start { apply\_on ="PublishedVersions" }} You can see the modified Terraform template here. You can deploy the sample application with Terraform and take advantage of SnapStart.
This section describes how the deployment changes after enabling Lambda SnapStart.
Before adding Lambda versions, Lambda alias and SnapStart, this is the process of publishing new code to a function:
After you enable Lambda versions, Lambda alias and Lambda SnapStart, there are more steps to the deployment:
During the deployment of a Lambda version, Lambda creates a new execution environment and initializes it with the new code. Once the code is initialized, Lambda takes a Snapshot of the initialized code. The deployment now takes longer than it did without SnapStart as it takes additional time to initialize the execution environment and to create the initialized function snapshot.
While the new Lambda version is being created, the Lambda alias remains unchanged and invokes the previous Lambda version when invoked. The calling application is unaware of the deployment; therefore, the additional deployment time does not impact calling applications.
When the new function version is ready, you can update the Lambda alias to point at the new Lambda version (this is done automatically in the preceding IaC examples).
By using a Lambda alias, you don’t need to direct all the Lambda invocations to the latest version. You can use the Alias routing configuration to shift traffic gradually to the new Lambda version, giving you an easier way to test new Lambda versions gradually and rollback in case of issues with the latest version.
There is an additional failure mode with this deployment. The initialization of a new Lambda version can fail in case of errors within the code. For example, Lambda does not initialize your code if there is an unhandled exception during the initialization phase. This is an additional failure mode that you must handle in the deployment cycle.
The first consideration is that enabling Lambda SnapStart increases the deployment time.
When your CI/CD pipeline deploys a new SnapStart-enabled Lambda version, Lambda initializes a new Lambda execution environment and takes a snapshot of both the memory and disk of the initialized code. This takes time and its latency would depend on the initialization time of your Lambda function, and the overall size of the snapshot.
This additional delay could be significant for CI/CD pipelines with large number of Lambda functions. Therefore, if you have an application with multiple Lambda functions, enable Lambda SnapStart on the Lambda functions gradually, and adjust the CI/CD pipeline timeout accordingly.
With Lambda SnapStart, there is an additional failure mode that you would need to handle in your CI/CD pipeline.
As described earlier, during the new Lambda version creation there could be failures linked to the code initialization of the Lambda code. This additional failure scenario can be managed in 2 ways:
This blog post shows the steps needed to leverage Lambda SnapStart, with examples for AWS CloudFormation, AWS SAM, and Terraform.
When you use the feature, there are additional steps that Lambda performs during the deployment. Lambda initializes a new Lambda version with the new code and takes a snapshot. This operation takes time and may fail if the code initialization fails, therefore you may need to make adjustments to your CI/CD pipeline to handle those scenarios.
If you’d like to learn more about the Lambda SnapStart feature, read more on the AWS Lambda Developer Guide or visit our Java on AWS Lambda workshop. To read more about this and other features, visit Serverless Land.