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

Vadym Kazulkin - Jun 3 - - Dev Community

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:

      SnapStart:
        ApplyOn: PublishedVersions
Enter fullscreen mode Exit fullscreen mode

to the Properties: section of the Lambda function

public void beforeCheckpoint(org.crac.Context<? extends Resource> context) throws Exception {
            auroraServerlessV2DataApiDao.getProductById("0");
      }
Enter fullscreen mode Exit fullscreen mode

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);
      }
Enter fullscreen mode Exit fullscreen mode

Additionally we need to include the following dependecy

<dependency>
  <groupId>io.github.crac</groupId>
  <artifactId>org-crac</artifactId>
  <version>0.1.3</version>
</dependency>
Enter fullscreen mode Exit fullscreen mode

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.
In the next part of the series we'll introduce various optimization strategies for the cold and warm starts.

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .