AWS SnapStart - Part 18 Measuring cold starts with Java 17 using different deployment artifact sizes
Tags: aws, java, serverless, coldstart
Published: 2024-04-11 14:41:09

## Introduction
In the [part 8](https://dev.to/aws-builders/measuring-lambda-cold-starts-with-aws-snapstart-part-8-measuring-with-java-17-21db) of our series we measured the cold start of the Lambda function with Corretto Java 17 runtime without SnapStart enabled, with SnapStart enabled and also applied DynamoDB invocation priming optimization. Lambda functions had 1024 MB memory and the deployment package (jar file) was approx. 15 MB. In this article we will make the same measurements but play around deployment package size to figure out whether it will make a difference similar as we did in the article [Measuring cold starts with Java 21 using different deployment artifact sizes ](https://dev.to/aws-builders/aws-snapstart-part-11-measuring-cold-starts-with-java-21-using-different-deployment-artifact-sizes-4g29) but now using Java 17.

## Measuring cold starts with Java 17 with and without SnapStart enabled using deployment artifact sizes 

Lets's consider the same 3 scenarios for Java 17 (as we did for Java 21): 

1. [Small HelloWorld-style application](https://github.com/Vadym79/AWSLambdaJavaSnapStart/tree/main/pure-lambda-17-small) which consists of Lambda receiving the API Gateway request with product id and basically prints this id out. There is no persistence layer involved. The application is that simple, that there is no priming technique to be applied. There are only several dependencies declared in [pom.xml](https://github.com/Vadym79/AWSLambdaJavaSnapStart/blob/main/pure-lambda-17-small/pom.xml) like aws-lambda-java-core and slf4j-simple. The deployment size of such an application is 137 KB only. 
2. [Medium Size application with DynamoDB persistence](https://github.com/Vadym79/AWSLambdaJavaSnapStart/tree/main/pure-lambda-17). We'll re-use the application introduced in [part 8](https://dev.to/aws-builders/measuring-lambda-cold-starts-with-aws-snapstart-part-8-measuring-with-java-17-21db) for this. There are basically 2 Lambda functions which both respond to the API Gateway requests and retrieve product by id received from the API Gateway from DynamoDB. One Lambda function can be used with and without SnapStart and the second one uses SnapStart and DynamoDB request invocation priming. There are bunch of dependencies declared in [pom.xml](https://github.com/Vadym79/AWSLambdaJavaSnapStart/blob/main/pure-lambda-17/pom.xml) like aws-lambda-java-core, aws-lambda-java-events, slf4j-simple, crac, dynamodb and url-connection-client. The deployment size of such application is 15 MB.
3. [Big Size application with DynamoDB persistence and dependencies to many other AWS services] (https://github.com/Vadym79/AWSLambdaJavaSnapStart/tree/main/pure-lambda-17-big). It's similira to medium size application. There are basically 2 Lambda functions which both respond to the APIGateway requests and retrieve product by id received from the API Gateway from DynamoDB. One Lambda function can be used with and without SnapStart and the second one uses SnapStart and DynamoDB request invocation priming. There are bunch of dependencies declared in [pom.xml](https://github.com/Vadym79/AWSLambdaJavaSnapStart/blob/main/pure-lambda-17-big/pom.xml) like aws-lambda-java-core, aws-lambda-java-events, slf4j-simple, crac, dynamodb and url-connection-client. But we also declare man other dependencies to various differnt AWS service like sns, kinesis, eventbridge, bedrock, but we won't even use them in our application. So such declaration makes only the package size bigger is then 50 MB.

The results of the experiment below were based on reproducing approximately 100 cold starts, which were reproduced during the experiment which ran for approximately 1 hour. All Lambda functions had 1024 MB memory setting.

Legend: **SMALL** - corresponds to 137 KB deployment artifact size, **MEDIUM** to 15 MB and **BIG** to 50 MB.

| Experiment description                     | p50      | p90       |p99       |
|---------------------------  |----------|-----------|----------|
|SMALL: cold start time w/o SnapStart                | 448.97  | 481.98   | 521.06  |
|SMALL: cold start time with SnapStart w/o Priming  | 475.76  | 611.43   | 734.14  |
|SMALL: cold start time with SnapStart with Priming | 475.76   | 611.43   | 734.14  |
|MEDIUM: cold start time w/o SnapStart                | 2847.00  | 2963.13   | 3181.06  |
|MEDIUM: cold start time with SnapStart w/o Priming  | 1513.85  | 1648.55   | 1860.34  |
|MEDIUM: cold start time with SnapStart with Priming | 725.56   | 829.03    | 1066.98  |
|BIG: cold start time w/o SnapStart                | 2930.74  | 3080.92   | 3281.16  |
|BIG: cold start time with SnapStart w/o Priming  | 1497.19  | 2195.47   | 2644.03  |
|BIG: cold start time with SnapStart with Priming | 731.94   | 1391.84    | 1679.56  |

For the small deployment artifact size cold start time with SnapStart enabled and with and without Priming are the same because there is nothing to prime is this simple case.


## Conclusions

There are some interesting insights coming from those measurements aso concerning the usage of SnapStart itself: for the small deployment size there is no real benefit of using SnapStart as cold start times with and without it are quite comparable. But applications and Lambda functions without any real dependencies incuding those to other AWS services are quite exceptional.

There is also quite noticable cold start difference for p90 and p99 comparing medium and big deployment artifact sizes whereas p50 remained similar. And of course cold starts for medium and big deployment sizes are much bigger than with the small one. So also for Java 21 the deployment size still plays a crucial role for the cold start without usage of the SnapStart but also with! Try to make your Lambda functions small and single-purposed!

Comparing these measurements with the same measurements done for [Java 21](https://dev.to/aws-builders/aws-snapstart-part-11-measuring-cold-starts-with-java-21-using-different-deployment-artifact-sizes-4g29)  we observe a bit lower cold start times for Java 17 in case SnapStart is not being enabled for all 3 package sizes for our use case. In case SnapStart is enabled the results are much closer for both with and without priming.