AWS SnapStart - Part 13 Measuring warm starts with Java 21 using different Lambda memory settings
Tags: aws, java, serverless, coldstart
Published: 2024-01-15 16:14:35

## Introduction
In the [part 12](https://dev.to/aws-builders/aws-snapstart-part-12-measuring-cold-starts-and-deployment-time-with-java-21-using-different-lambda-memory-settings-35hl) of our series we measured the cold starts of the Lambda function with Corretto Java 21 runtime without SnapStart enabled, with SnapStart enabled and also applied DynamoDB invocation priming optimization with different memory settings.

In this article we'll also provide measurements for the warm execution times for this use case, as using different Lambda memory settings not only affect the cold start times but also the warm execution times and Lambda costs.

## Measuring warm starts with Java 21 with and without SnapStart enabled using different Lambda memory settings.

In our experiment we'll re-use the application introduced in [part 9](https://dev.to/aws-builders/measuring-lambda-cold-starts-with-aws-snapstart-part-9-measuring-with-java-21-5e52) 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 GetProductByIdWithPureJava21Lambda can be used with and without SnapStart and the second one GetProductByIdWithPureJava21LambdaAndPriming uses SnapStart and DynamoDB request invocation priming. We'll measure cold and warm starts using the following memory settings in MBs : 256, 512, 768, 1024, 1536 and 2048.
I also put the cold starts measured in the [part 12](https://dev.to/aws-builders/aws-snapstart-part-12-measuring-cold-starts-and-deployment-time-with-java-21-using-different-lambda-memory-settings-35hl) into the tables to see both cold and warm starts in one place. The results of the experiment below were based on reproducing more than 100 cold and approximately 100.000 warm starts for the duration of our experiment which ran for approximately 1 hour. Here is the code for the [sample application](https://github.com/Vadym79/AWSLambdaJavaSnapStart/tree/main/pure-lambda-21). For it (and experiments from my previous article) I used the load test tool [hey](https://github.com/rakyll/hey), but you can use whatever tool you want, like [Serverless-artillery](https://www.npmjs.com/package/serverless-artillery) or [Postman](https://www.postman.com/). Abbreviation **c** is for the cold start and **w** is for the warm start.

**Cold (c) and warm (w) start times without SnapStart  in ms:**

|RAM| c p50  | c p75 | c p90 |c p99 | c p99.9| c max |w p50 | w p75 | w p90 |w p99 | w p99.9 | w max |      
|-----------|----------|-----------|----------|----------|----------|----------|-----------|----------|----------|----------|----------|-------|
|256 MB  | 8056.84| 8298.23|8494.11 |9123.72 |9256.72 |9417.65 |6.02|10.96|18.72|60.03|154.44|6677.71|
|512 MB | 4684.92| 4781.67| 4944.95 |5014.81 |5156.32 |5321.34 |5.55|6.41|8.26|29.87|78.66|3142.8|
|768 MB |3638.06 |3720.91 |3815.31|4636.18 |4787.51 |4895.48 |5.55|6.30|7.75|21.75|90.74|1991.17|
|1024 MB | 3157.6|3213.85 |3270.8 |3428.2 |3601.12 |3725.02 |5.77|6.50|7.81|20.65|90.20|1423.63|
|1536 MB |2665.49| 2700.56|2808.68|3306.94 |3476.05 |3613.84 |5.82|6.61|7.88|18.62|57.73|918.37|
|2048 MB |2414.66|2463.17 |2521.7|2839.59|3012.07|3156.33 |5.68|6.40|7.57|17.89|44.74|809.96|

Let's put this data into graph, but skip the max value (it's to high so it's difficult to see p50 and p75 values) :


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ojaqzou6a6qi5dppm5ab.png)


**Cold (c) and warm (w) start times with SnapStart without Priming  in ms:**

|RAM| c p50  | c p75 | c p90 |c p99 | c p99.9| c max |w p50 | w p75 | w p90 |w p99|w p99.9 | w max |      
|-----------|----------|-----------|----------|----------|----------|----------|-----------|----------|----------|----------|----------|-------|
|256 MB|5623.35|5736.89|6526.39|7020.38|7076.74|7080.47 |6.21|12.43|19.93|65.98|164.48|6051.3|
|512 MB|2861.27|3035.06|3504.91|3881.08|3927.91|3931.82|5.64 |6.51|8.66|30.35|90.74|2814.54|
|768 MB|1976.74|2053.27|2492.62|2787.87 |2799.04 |2801.67 |5.47|6.11|7.39|21.40|73.82|1986.51|
|1024 MB| 1626.69|1741.10| 2040.99|2219.75 |2319.54 |2321.64 |5.64|6.41|7.87|21.40|99.81|1355.09|
|1536 MB| 1312.14|1369.76|1703.23 |1753.32|2078.04|2078.96|5.64 |6.30|7.51|18.55|70.39|873.66|
|2048 MB|1172.00|1282.32|1612.12 |1845.01|2312.60|2313.33 |5.73|6.51 |7.87|20.09|104.68|924.65|

Let's put this data into graph, but skip the max value:


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/t8fb12wriri3gtybbz1s.png)

**Cold (c) and warm (w) start times with SnapStart and with DynamoDB invocation Priming  in ms:**

|RAM| c p50  | c p75 | c p90 |c p99 | c p99.9| c max |w p50 | w p75 | w p90 |w p99 | w p99.9 | w max |      
|-----------|----------|-----------|----------|----------|----------|----------|-----------|----------|----------|----------|----------|-------|
|256 MB|1135.11|1227.14| 1457.33|1713.47 |1715.19 |1716.63 |5.84|13.66|22.61|72.52|479.98|694.68|
|512 MB|862.32|935.03|1206.47|1394.62 |1398.81 |1399.09|5.64 |6.51|8.80|30.35|79.92|547.74|
|768 MB|839.36|918.36|1107.10|1248.17|1387.67|1389.05|5.73|6.61 |8.00|22.81|61.02|307.75|
|1024 MB|702.55|759.52|1038.50|1169.66|1179.05|1179.36|5.73|6.51 |7.87|21.75|92.19|328.41|
|1536 MB| 659.02|723.22|981.97|1254.43|1376.62|1377.26|5.47 |6.21|7.51|18.26|75.00|233.04|
|2048 MB|687.96|763.32 |1054.18|1174.35|1184.96|1186.08|5.92 |6.83|8.66 |20.41|89.31|339.88|

Let's put this data into graph, but skip the max value:

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6jh6n88b6d0txo8ramhq.png)

## Conclusions

In this article we measured the warm start time of the Lambda function without SnapStart with SnapStart and for the latter with additional priming of DynamoDB invocation using different Lambda memory settings.

In case of not enabling SnapStart for the Lambda function we observed that increasing memory reduces the warm execution time for our use case especially for p>90. As adding more memory to the Lambda function is also a cost factor, the sweet spot between cold and warm start time and cost is somewhere between 768 and 1204 MB memory setting for the Lambda function for our use case. You can use [AWS Lambda Power Tuning](https://github.com/alexcasalboni/aws-lambda-power-tuning) for very nice visualisations.

We made similar observations in the case of enabling SnapStart for the Lambda function without and with additionally using priming of DynamoDB invocation request. The sweet spot between cold and warm start time and cost is somewhere between 768 and 1024 MB memory setting for the Lambda function for our use case as well. In case of no priming usage, we also see some improvements in maximal values for the warm execution by adding more memory than 1024 MB. 

In case of applying priming of the DynamoDB invocation there is only little to no improvements of the cold and warm execution times using more than 1024 MB memory even for p99, p99.9 and maximal values.

In the next articles we'll also provide measurements for the cold and warm execution times for the same sample application using different memory settings but for Java 17 and we'll compare the measurements between Java 21 and 17 runtimes. Stay tuned!