Data API for Amazon Aurora Serverless v2 with AWS SDK for Java – Part 7 Data API meets SnapStart

RMAG news

Introduction

In the part 5 we measured cold and warm starts of our sample application which uses Data API for Amazon Aurora Serverless v2 with AWS SDK for Java and in the part 6 we did the same measurements using the standard connection management solutions like JDBC including the usage of the Amazon RDS Proxy service and compared the result. In this part of the series we’ll enable AWS SnapStart to the Lambda function communicating with Aurora Serverless v2 PostgreSQL via Data API and also apply optimization technique called priming.

Measuring cold and warm starts with SnapStart enabled and priming

I released a separate series about AWS Lambda SnapStart where I talked about its benefits and also measured warm and cold starts for the similar application which also used Java 21 managed Lambda runtime but DynamoDB database instead of Aurora Serverless v2 with Data API.

In our experiment we’ll re-use the application introduced in the part 1 for this which you can find here.

We will measure cold and warm start for 2 approaches:

Enable SnapStart for Lambda function GetProductByIdViaAuroraServerlessV2DataApi by adding

SnapStart:
ApplyOn: PublishedVersions

to the Properties: section of the Lambda function

Additionally apply priming technique to the Lambda function with SnapStart enabled by priming the database request. I explained priming in my article Measuring priming, end to end latency and deployment time with Java . In our case I implemented additional Lambda function GetProductByIdViaAuroraServerlessV2DataApiWithPriming. In its implementation GetProductByIdViaAuroraServerlessV2DataApiWithPrimingHandler you can see how priming works in action :

public void beforeCheckpoint(org.crac.Context<? extends Resource> context) throws Exception {
            auroraServerlessV2DataApiDao.getProductById(“0”);
      }

In the beforeCheckpoint Lambda runtime hook method (which uses CRaC API) we prime database invocation by retrieving the product with id equals to 0 from the database using Data API for Aurora Serverless v2. With that we pre-initialize all the classes involved in the invocation chain and pre-initilizing synchronous HTTP client (we use the default one which is Apache) which all will be directly available after the Firecracker microVM is restored.

For that our Lambda handler needs to implement org.crac.Resource interface, and register this class to be CRaC-aware with:

public GetProductByIdViaAuroraServerlessV2DataApiWithPrimingHandler() {
            Core.getGlobalContext().register(this);
      }

Additionally we need to include the following dependecy

<dependency>
<groupId>io.github.crac</groupId>
<artifactId>org-crac</artifactId>
<version>0.1.3</version>
</dependency>

in the pom.xml.

The results of the experiments to retrieve the existing product from the database by its id see below were based on reproducing more than 100 cold and at least 30.000 warm starts with experiment which ran for approximately 1 hour. 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.

Cold (c) and warm (m) start time in ms:

Approach
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

No SnapStart enabled
3154.35
3237
3284.91
3581.49
3702.12
3764.92
104.68
173.96
271.32
572.11
1482.89
2179.7

SnapStart enabled without priming
1856.11
1994.61
2467.83
3229.11
3238.80
3241.75
61.02
113.32
185.37
639.35
1973.30
2878.5

SnapStart enabled with priming of database invocation via Data API
990.84
1069.04
1634.84
2120.00
2285.03
2286.9
60.06
106.35
185.37
581.27
1605.37
2658.24

Conclusion

In this part of the series, we applied SnapStart to the Lambda function and also convinced that it significantly reduced the cold and the warm start of our Lambda function. It was especially true when we also applied priming of Data API invocation.