Data API for Amazon Aurora Serverless v2 with AWS SDK for Java - Part 6 Comparing cold and warm starts between Data API and JDBC
Tags: aws, java, serverless, database
Published: 2024-05-06 15:10:56

## Introduction

In the [part 1](https://dev.to/aws-builders/data-api-for-amazon-aurora-serverless-v2-with-aws-sdk-for-java-part-1-introduction-and-set-up-of-the-sample-application-3g71) of the series we set up our sample application which has API Gateway in front of Lambda functions which communicate with Aurora Serverless v2 PostgreSQL database via Data API to create the products and retrieve them (by id). In the [part 2](https://dev.to/aws-builders/data-api-for-amazon-aurora-serverless-v2-with-aws-sdk-for-java-part-2-executing-sql-statements-4kon) we dove dive deeper into the new Data API for Aurora Serverless v2 itself and its capabilities like executing SQL Statements and used AWS SDK for Java for it. In the [part 3](https://dev.to/aws-builders/data-api-for-amazon-aurora-serverless-v2-with-aws-sdk-for-java-part-3-executing-update-and-insert-sql-statements-in-batch-3ajc) we explored Data API capabilities to batch SQL statement over an array of data for bulk update and insert operations. In the [part 4](https://dev.to/aws-builders/data-api-for-amazon-aurora-serverless-v2-with-aws-sdk-for-java-part-4-working-with-database-transactions-555m/edit) of the series we explored how to use database transactions with Data API and in the [part 5](https://dev.to/aws-builders/data-api-for-amazon-aurora-serverless-v2-with-aws-sdk-for-java-part-5-basic-cold-and-warm-starts-measurements-4gi9) we made cold and warm start measurements of the Data API for the Aurora Serverless v2 without usage of Lambda SnapStart.

In this article I make the comparison of the cold and warm starts between 4 scenarios of connecting Lambda function to the Amazon Aurora Serverless v2:

1. Using Data API, see [part 5](https://dev.to/aws-builders/data-api-for-amazon-aurora-serverless-v2-with-aws-sdk-for-java-part-5-basic-cold-and-warm-starts-measurements-4gi9).
2. Using Amazon RDS Proxy for database connection management and JDBC. I also refer to my [article](https://dev.to/aws-builders/how-to-set-up-amazon-rds-proxy-for-amazon-aurora-serverless-database-cluster-and-connect-aws-lambda-function-to-it-20m5) for further details about RDS Proxy setup for our scenario.
3. Using new database connecton per Lambda invocation and JDBC.
4. Re-using one database connection per Lambda life cycle and JDBC.

# Measuring cold and warm measurements with using the standard connection management solutions with JDBC

In our experiment we'll re-use the application introduced in the [part 1](https://dev.to/aws-builders/data-api-for-amazon-aurora-serverless-v2-with-aws-sdk-for-java-part-1-introduction-and-set-up-of-the-sample-application-3g71). You can find the source code [here](https://github.com/Vadym79/AWSLambdaJavaAuroraServerlessV2DataApi). For the executing those experiments we need to deploy the following SAM template [template-with-and-without-data-api-and-rds-proxy.yaml](https://github.com/Vadym79/AWSLambdaJavaAuroraServerlessV2DataApi/blob/master/template-with-and-without-data-api-and-rds-proxy.yaml) by executing **sam deploy -t template-with-and-without-data-api-and-rds-proxy.yaml**.

This template introduces 2 additional Lambda functions:

- GetProductByIdViaAuroraServerlessV2WithoutDataApi for retrieving product by id using JDBC and without using Amazon RDS Proxy. Here you can find the implementation of the   [GetProductByIdViaAuroraServerlessV2WithoutDataApiHandler](https://github.com/Vadym79/AWSLambdaJavaAuroraServerlessV2DataApi/blob/master/src/main/java/software/amazonaws/example/product/handler/GetProductByIdViaAuroraServerlessV2WithoutDataApiHandler.java). This handler by default was used for 2 upcoming measurements: 

1. creating PostgreSQL database connection once for the lifetime of the Lambda function and then always reusing it.

2.  always creating the new database connection for each Lambda execution can be achieved by the small source code modification of the **createConnection** function:
 
```
private Connection createConnection (String url, String userName, String userPassword) throws SQLException {
      return  DriverManager.getConnection(url, userName, userPassword);   
}
```
Both approaches are only explored for the demonstration purposes and they don't introduce the proper connection management/pool technique
- GetProductByIdViaAuroraServerlessV2WithRDSProxy for retrieving product by id using JDBC and with using Amazon RDS Proxy. Here you can find the implementation of the   [GetProductByIdViaAuroraServerlessV2RDSProxyHandler](https://github.com/Vadym79/AWSLambdaJavaAuroraServerlessV2DataApi/blob/master/src/main/java/software/amazonaws/example/product/handler/GetProductByIdViaAuroraServerlessV2RDSProxyHandler.java). This approach introduces the proper scalable connection management/pool technique. In the [template-with-and-without-data-api-and-rds-proxy.yaml](https://github.com/Vadym79/AWSLambdaJavaAuroraServerlessV2DataApi/blob/master/template-with-and-without-data-api-and-rds-proxy.yaml) you can explore how to setup Amazon RDS Proxy with Infrastructure as a Code. I also refer to my article [How to set up Amazon RDS Proxy for Amazon Aurora (Serverless) database cluster and connect AWS Lambda function to it](https://dev.to/aws-builders/how-to-set-up-amazon-rds-proxy-for-amazon-aurora-serverless-database-cluster-and-connect-aws-lambda-function-to-it-20m5) for further details.

**The word of caution:** only for demonstration purpose I passed the database name and password as the Lambda environment variables to connect to RDS Proxy which introduces the security risk. The proper solution is to store the database password in Amazon Secret Manager and then retrieve in the Lambda function.

The results of the experiments to retrieve the existing product from the database with all approaches by its id with Lambda functions with 1024 MB memory setting were based on reproducing more than 100 cold and approximately 10.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](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/). We won't enable SnapStart on the Lambda functions first.

**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|      
|---------------|----------|-----------|----------|----------|----------|----------|-----------|----------|----------|----------|----------|----------|
|New database connecton per Lambda invocation|2455.53|2727.23|2942.48|3354.11|3684.52|3685.73|1084.10|1383.52|1693.04|2291.89|2782.31|3069.79|
|One database connection reused per Lambda life cycle|1983.14|2061.53|2137.93|2243.39|2445.59|2587.12|3.42|18.72|49.69|77.23|175.17|1619.61|
|Amazon RDS Proxy|1972.80|2063.56|2221.97|2426.25|2520.18|2522.17|143.79|179.57|197.52|361.05|1348.17|1752.54|
|Data API, see  [part 5](https://dev.to/aws-builders/data-api-for-amazon-aurora-serverless-v2-with-aws-sdk-for-java-part-5-basic-cold-and-warm-starts-measurements-4gi9)|3154.35|3237|3284.91|3581.49|3702.12|3764.92|104.68|173.96|271.32|572.11|1482.89|2179.7|


## Conclusion
In this part of the series, we compared warm and cold start measurement of Data API for Amazon Aurora Serverless v2 with AWS SDK for Java with the same measurements using the standard connection management with JDBC. The most important comparison is with using Amazon RDS Proxy by providing scalable database connection management solution for PostgreSQL database and we saw that Data API introduces higher cold start times but quite competitive warm start times comparing to using RDS Proxy. In the next part of the series we'll explore to how to optimize warm and cold start times of Data API for Amazon Aurora Serverless v2 using Lambda SnapStart and priming techniques.