Introduction
In this article series we already introduced how to develop, run and optimize GraalVM Native Image application on AWS Lambda deployed as Lambda Custom Runtime. In the part 5 we upgraded our sample application to use GraalVM 23 and Native Image. In November 2024 AWS CRT Client for Java added GraalVM Native Image support. In this article we'll modify our sample application to use AWS CRT HTTP client instead of Apache one and measure the performance (cold and warm start time) of the Lambda function and make comparison between these 2 HTTP clients.
How to write AWS Lambda function with GraalVM 23 and AWS CRT HTTP Client
The sample simple application introduced in the part 5 remains the same, see the architecture below:
But I modified it to use AWS CRT HTTP Client and published the source code in the pure-lambda-graalvm-23-native-image-with-aws-crt-http-client repository.
Following changes needed to be done in the part 5 to use AWS CRT HTTP Client instead of Apache one:
1) In pom.xml
declare AWS CRT HTTP Client :
<dependency>
<groupId>software.amazon.awssdk</groupId>
<artifactId>aws-crt-client</artifactId>
</dependency>
and exclude Apache HTTP Client :
<exclusions>
<exclusion>
<groupId>software.amazon.awssdk</groupId>
<artifactId>apache-client</artifactId>
</exclusion>
</exclusions>
2) In DynamoProductDao set AWS CRT HTTP Client:
private static final DynamoDbClient dynamoDbClient = DynamoDbClient.builder()
....
.httpClient(AwsCrtHttpClient.create())
.build();
3) In native.xml include during the build process automatically generated libaws-crt-jni.so (as described in the article AWS CRT Client for Java added GraalVM Native Image support) to be added to the Lambda Custom Runtime zip file:
<fileSet>
...
<includes>
<include>aws-pure-lambda-graalvm-23-native-image-aws-crt-http-client </include>
<include>libaws-crt-jni.so</include>
</includes>
</fileSet>
Following needs to be installed in order to build and deploy the sample application:
- Java 21, for example Amazon Corretto 21
- Apache Maven
- AWS CLI
- AWS SAM
- GraalVM, for example GraalVM 23.0.1
- Native Image
In order to build the application, execute mvn clean package
.
In order to build the application, execute sam deploy -g
.
In order to create the product with id equal to 1, execute
curl -m PUT -d '{ "id": 1, "name": "Print 10x13", "price": 0.15 }' -H "X-API-Key: a6ZbcDefQW12BN56WEC23" https://{$API_GATEWAY_URL}/prod/products
In order to retrieve the product with id equal to 1, execute
curl -H "X-API-Key: a6ZbcDefQW12BN56WEC23" https://{$API_GATEWAY_URL}/prod/products/1
What I noticed was that the compiled artifact size to be deployed using AWS CRT HTTP Client was bigger than using Apache one (37.600 vs 34.700 KB) mainly due to additional native .so file. Bigger artifact sizes generally contribute to the higher cold start times. So, let's see.
Measuring cold and warm start time of the AWS Lambda function with GraalVM 23 and AWS CRT HTTP Client
How to measure AWS Lambda performance introduced in the part 5 a still remains valid.
The results of the experiment below were as well based on reproducing more than 100 cold and approximately 100.000 warm starts with Lambda function GetProductByIdFunction with 1024 MB memory setting for the duration of 1 hour. The experiments have been performed with the Lambda Custom Runtime version provided:al2023.v56. For it I used the load test tool hey, but you can use whatever tool you want, like Serverless-artillery or Postman.
So let's provide the results of the measurements. I will also add measurements from the part 5 performed with the Apache HTTP Client for better visualization.
Abbreviation c stays for the cold start and w is for the warm start.
Cold (c) and warm (w) start time in ms with :
HTTP Client | 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 |
---|---|---|---|---|---|---|---|---|---|---|---|---|
Apache | 618.18 | 628.78 | 638.28 | 667.64 | 705.37 | 705.61 | 4.03 | 4.62 | 5.25 | 10.33 | 38.76 | 103.27 |
AWS CRT | 675.02 | 685.22 | 699.75 | 743.74 | 930.12 | 930.37 | 3.91 | 4.37 | 4.97 | 9.31 | 64.03 | 228.41 |
Conclusion
In this article we modified our sample application to use AWS CRT HTTP client instead of Apache one and measured the performance (cold and warm start time) of the Lambda function.
We observe that the cold start times for Apache HTTP Client are lower than for AWS CRT one for all percentiles (for the higher one significantly). The warm start times for lower percentiles are slightly better for AWS CRT HTTP Client and become worse comparing to Apache HTTP Client for the higher percentiles.
As long as I don't identify any optimization potential for my sample application I'd prefer to use Apache HTTP Client, but the measurements and therefore the choice may be different for your application. So measure it yourself!
If you have read my article(s) and liked its content, please support me by following me on my GitHub account and giving my repos a star.
Top comments (0)