DEV Community

Vadym Kazulkin for AWS Community Builders

Posted on • Edited on

AWS SnapStart - Part 13 Measuring warm starts with Java 21 using different Lambda memory settings

Introduction

In the part 12 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 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 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. For it (and experiments from my previous article) I used the load test tool hey, but you can use whatever tool you want, like Serverless-artillery or Postman. 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

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

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

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 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!

Top comments (0)