DEV Community

Vadym Kazulkin for AWS Heroes

Posted 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 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:

Image description

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>
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

Following needs to be installed in order to build and deploy the sample application:

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.

Billboard image

Deploy and scale your apps on AWS and GCP with a world class developer experience

Coherence makes it easy to set up and maintain cloud infrastructure. Harness the extensibility, compliance and cost efficiency of the cloud.

Learn more

Top comments (0)

Heroku

Simplify your DevOps and maximize your time.

Since 2007, Heroku has been the go-to platform for developers as it monitors uptime, performance, and infrastructure concerns, allowing you to focus on writing code.

Learn More

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay