DEV Community

Vadym Kazulkin for AWS Heroes

Posted on • Edited on

Lambda function with GraalVM Native Image - Part 6 Measuring cold and warm starts with GraalVM 23 and AWS CRT HTTP Client

Introduction

In this article series, we already introduced how to develop, run, and optimize a GraalVM Native Image application on AWS Lambda deployed as a Lambda Custom Runtime. In 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 a comparison between these 2 HTTP clients.

How to write an 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.

The following changes needed to be done in part 5 to use AWS CRT HTTP Client instead of the Apache one:

1) In pom.xml,

declare AWS CRT HTTP Client :

<dependency>
    <groupId>software.amazon.awssdk</groupId>
    <artifactId>aws-crt-client</artifactId>
</dependency>
Enter fullscreen mode Exit fullscreen mode

and exclude Apache HTTP Client :

<exclusions>
     <exclusion>              
         <groupId>software.amazon.awssdk</groupId>
         <artifactId>apache-client</artifactId>
     </exclusion>
</exclusions>
Enter fullscreen mode Exit fullscreen mode

2) In DynamoProductDao set AWS CRT HTTP Client:

  private static final DynamoDbClient dynamoDbClient = DynamoDbClient.builder()
     ....
    .httpClient(AwsCrtHttpClient.create())
    .build();
Enter fullscreen mode Exit fullscreen mode

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

The following needs to be installed to build and deploy the sample application:

To build the application, execute mvn clean package.
To build the application, execute sam deploy -g.

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

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 the Apache one (37.600 vs 34.700 KB), mainly due to an 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 part 5, remains valid.

The results of the experiment below were also based on reproducing more than 100 cold and approximately 100.000 warm starts with the Lambda function GetProductByIdFunction with a 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 part 5 performed with the Apache HTTP Client, for better visualization.

Abbreviation c stands for the cold start, and w stands for the warm start.

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

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 the AWS CRT HTTP client instead of the 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 for all percentiles (for the higher ones significantly). The warm start times for lower percentiles are slightly better for AWS CRT HTTP Client and become worse compared 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 articles and liked their content, please support me by following me on my GitHub account and giving my repos a star.

Top comments (0)