Practical Performance Tuning for Serverless Java on AWS- InfoQ Dev Summit

VadymKazulkin 9 views 87 slides Oct 18, 2025
Slide 1
Slide 1 of 87
Slide 1
1
Slide 2
2
Slide 3
3
Slide 4
4
Slide 5
5
Slide 6
6
Slide 7
7
Slide 8
8
Slide 9
9
Slide 10
10
Slide 11
11
Slide 12
12
Slide 13
13
Slide 14
14
Slide 15
15
Slide 16
16
Slide 17
17
Slide 18
18
Slide 19
19
Slide 20
20
Slide 21
21
Slide 22
22
Slide 23
23
Slide 24
24
Slide 25
25
Slide 26
26
Slide 27
27
Slide 28
28
Slide 29
29
Slide 30
30
Slide 31
31
Slide 32
32
Slide 33
33
Slide 34
34
Slide 35
35
Slide 36
36
Slide 37
37
Slide 38
38
Slide 39
39
Slide 40
40
Slide 41
41
Slide 42
42
Slide 43
43
Slide 44
44
Slide 45
45
Slide 46
46
Slide 47
47
Slide 48
48
Slide 49
49
Slide 50
50
Slide 51
51
Slide 52
52
Slide 53
53
Slide 54
54
Slide 55
55
Slide 56
56
Slide 57
57
Slide 58
58
Slide 59
59
Slide 60
60
Slide 61
61
Slide 62
62
Slide 63
63
Slide 64
64
Slide 65
65
Slide 66
66
Slide 67
67
Slide 68
68
Slide 69
69
Slide 70
70
Slide 71
71
Slide 72
72
Slide 73
73
Slide 74
74
Slide 75
75
Slide 76
76
Slide 77
77
Slide 78
78
Slide 79
79
Slide 80
80
Slide 81
81
Slide 82
82
Slide 83
83
Slide 84
84
Slide 85
85
Slide 86
86
Slide 87
87

About This Presentation

Java is for many years one of the most popular programming languages, but it is known for its high cold start times and high memory footprint, compared to other programming languages like Node.js and Python.

In this talk we'll look at the general best practices and techniques we can use to dec...


Slide Content

Vadym Kazulkin| @VKazulkin |ip.labsGmbH1 High performance Serverless Java on AWS

Vadym Kazulkin| @VKazulkin |ip.labsGmbH
Vadym Kazulkin
ip.labs GmbH Bonn, Germany
Co-Organizer of the Java User Group Bonn
[email protected]
@VKazulkin
https://dev.to/vkazulkin
https://github.com/Vadym79/
https://de.slideshare.net/VadymKazulkin/
https://www.linkedin.com/in/vadymkazulkin
https://www.iplabs.de/
Contact

Vadym Kazulkin| @VKazulkin |ip.labsGmbH
Java Popularity
Vadym Kazulkin | @VKazulkin | ip.labs GmbH

Vadym Kazulkin| @VKazulkin |ip.labsGmbH
https://distantjob.com/blog/programming-languages-rank/

Vadym Kazulkin| @VKazulkin |ip.labsGmbH
Life of the Java
(Serverless)
Developer
on AWS
6

Vadym Kazulkin| @VKazulkin |ip.labsGmbH
▪Corretto Java 8
▪With extended long-term support until 2026
▪Coretto Java 11 (since 2019)
▪Coretto Java 17 (since April 2023)
▪Corretto Java 21(since November 2023)
▪Waiting for the support of Java 25
▪Only Long Term Support (LTS) by AWS
AWS Java Versions Support for AWS Lambda
7

Vadym Kazulkin| @VKazulkin |ip.labsGmbH
…but
serverless
adoption of
Java looks like
this!
8
Java is a very
fast and
mature
programming
language…

Vadym Kazulkin| @VKazulkin |ip.labsGmbH
Percent of AWS Lambda Invocations by Language
2021 vs 2023
https://www.datadoghq.com/state-of-serverless-2021
https://www.datadoghq.com/state-of-serverless/
PHYTON IS THE
MOST POPULAR
LAMDA
RUNTIME

Vadym Kazulkin| @VKazulkin |ip.labsGmbH
Developers love Java and will be happy
to use it for Serverless applications
But what are the challenges ?
10

Vadym Kazulkin| @VKazulkin |ip.labsGmbH
▪“cold start” times (latencies)
▪memory footprint (high cost in AWS)
Serverless with Java Challenges

Vadym Kazulkin| @VKazulkin |ip.labsGmbH
Demo Application
https://github.com/Vadym79/AWSLambdaJavaSnapStart

Vadym Kazulkin| @VKazulkin |ip.labsGmbH
https://docs.aws.amazon.com/apigateway/latest/developerguide/set-up-lambda-proxy-integrations.html#api-gateway-simple-proxy-for-lambda-input-format
API Gateway Proxy Request Event JSON

Vadym Kazulkin| @VKazulkin |ip.labsGmbH
AWS Lambda Function with Java runtime
14

Vadym Kazulkin| @VKazulkin |ip.labsGmbH
Challenge No. 1
A Big Cold-Start

Vadym Kazulkin| @VKazulkin |ip.labsGmbH
Lambda function lifecycle –a full cold start
16
Sources: Ajay Nair „Become a ServerlessBlack Belt” https://www.youtube.com/watch?v=oQFORsso2go
Tomasz Łakomy"Notes from Optimizing Lambda Performance for Your Serverless Applications“ https://tlakomy.com/optimizing-lambda-performance-for-serverless-applications

Vadym Kazulkin| @VKazulkin |ip.labsGmbH
▪When Lambda function has been invoked for the first time
▪After a new Lambda function was deployed
▪After the existing Lambda function code was modified and re-deployed
▪When there are not enough warm execution environments in the pool
▪More concurrent Lambda invocation requests as execution environments in the pool
▪When the execution environment was destroyed by AWS
▪For cost saving reasons as the execution environment wasn’t in use for a long time
▪For security and other reasons to patch the execution environment(s)
New Lambda function execution environment
required/Lambda function cold starts

Vadym Kazulkin| @VKazulkin |ip.labsGmbH
▪Start Firecracker VM (execution environment)
▪AWS Lambda starts the Java runtime
▪Java runtime loads and initializes Lambda function code
(Lambda handler Java class)
▪Class loading
▪Static initializer block of the handler class is executed (i.e.AWS service client
creation)
▪Runtime dependency injection
▪Just-in-Time (JIT) compilation
▪Lambda invokes the handler method
18
Sources: Ajay Nair „Become a Serverless Black Belt” https://www.youtube.com/watch?v=oQFORsso2go
Tomasz Łakomy"Notes from Optimizing Lambda Performance for Your Serverless Applications“ https://tlakomy.com/optimizing-lambda-performance-for-serverless-applications
Michael Hart: „Shave 99.93% off your Lambda bill with this one weird trick“ https://hichaelmart.medium.com/shave-99-93-off-your-lambda-bill-with-this-one-weird-trick-33c0acebb2ea
Lambda function lifecycle

Vadym Kazulkin| @VKazulkin |ip.labsGmbH
AWS Lambda Function with Java runtime
19
Invocation of the
handeRequest
method is the
warm start

Vadym Kazulkin| @VKazulkin |ip.labsGmbH
Demo Application
https://github.com/Vadym79/AWSLambdaJavaSnapStart
▪Lambda has 1024 MB memory setting
▪Lambda uses x86 architecture
▪Default (Apache) Http Client for
communication with DynamoDB
▪14 MB artifact size, , all dependencies in
the POM file
▪Java compilation option -
XX:+TieredCompilation -
XX:TieredStopAtLevel=1
▪Info about the experiments:
▪Approx. 1 hour duration
▪Approx. first* 100 cold starts
▪Approx. first 100.000 warm starts
*after Lambda function being re-deployed

Vadym Kazulkin| @VKazulkin |ip.labsGmbH
https://dev.to/aws-builders/aws-snapstart-part-13-measuring-warm-starts-with-java-21-using-different-lambda-memory-settings-160k
Measurements in
ms
p50 p75 p90 p99 p99.9 max
Amazon Corretto
Java 21 cold start
3158 3214 3270 3428 3601 3725
Amazon Corretto
Java 21 warm start
5,77 6,50 7,81 20,65 90,20 1423,63
Cold and warm starts with Java 21

Vadym Kazulkin| @VKazulkin |ip.labsGmbH
▪AWS SnapStart
▪GraalVM(Native Image)
Options To Reduce Cold Start Time
22

Vadym Kazulkin| @VKazulkin |ip.labsGmbH
AWS Lambda
SnapStart

Vadym Kazulkin| @VKazulkin |ip.labsGmbH
▪Lambda SnapStartfor Java can improve startup performance for latency-
sensitive applications
▪SnapStartis fully managed
AWS Lambda SnapStart
https://docs.aws.amazon.com/lambda/latest/dg/snapstart.html

Vadym Kazulkin| @VKazulkin |ip.labsGmbH
▪Currently available for Lambda managed Java Runtimes (Java 11, 17 and 21),
Python and .NET
▪Not available for all other Lambda runtimes:
▪Docker Container Image
▪Custom (Lambda) Runtime (a way to ship GraalVMNative Image)
AWS Lambda SnapStart
https://github.com/Vadym79/AWSLambdaJavaDockerImage/

Vadym Kazulkin| @VKazulkin |ip.labsGmbH
AWS SnapStartDeployment & Invocation
26
https://aws.amazon.com/de/blogs/compute/reducing-java-cold-starts-on-aws-lambda-functions-with-snapstart/
Vadym Kazulkin@VKazulkin, ip.labsGmbH
C
Create
Snapshot
Firecracker microVM
create & restore
snapshot

Vadym Kazulkin| @VKazulkin |ip.labsGmbH
AWS SnapStartDeployment & Invocation
https://dev.to/vkazulkin/measuring-java-11-lambda-cold-starts-with-snapstart-part-1-first-impressions-30a4
https://aws.amazon.com/de/blogs/compute/using-aws-lambda-snapstart-with-infrastructure-as-code-and-ci-cd-pipelines/

Vadym Kazulkin| @VKazulkin |ip.labsGmbH
AWS Lambda SnapStartwith Priming

Vadym Kazulkin| @VKazulkin |ip.labsGmbH
▪Pre-load as many Java classes as possible before the SnapStart
takes the snapshot
▪Java loads classes on demand (lazy-loading)
▪Pre-initialize as much as possible before the SnapStarttakes the
snapshot
▪Http Clients (Apache, UrlConnection) and JSON Marshallers (Jackson)
require expensive one-time initialization per (Lambda) lifecycle. They both
are used when creating Amazon DynamoDbClient
Ideas behind priming
29

Vadym Kazulkin| @VKazulkin |ip.labsGmbH
AWS SnapStartDeployment & Invocation
30
https://aws.amazon.com/de/blogs/compute/reducing-java-cold-starts-on-aws-lambda-functions-with-snapstart/
Vadym Kazulkin@VKazulkin, ip.labsGmbH
Lambda uses the
CRaCAPIsfor
runtime hooks
for Priming
C
Create
Snapshot
Firecracker microVM
create & restore snapshot

Vadym Kazulkin| @VKazulkin |ip.labsGmbH
▪Primedependencies during initialization phase (when it worth doing)
▪„Fake“ the calls to pre-initialize „some other expensive stuff“ or
execute some critical code paths (this technique is called Priming)
Priming

Vadym Kazulkin| @VKazulkin |ip.labsGmbH
Product Repository DAO class
Expensive initialization of the HTTP Client
Expensive initialization of the Jackson
Marshaller (ObjectMapper)

Vadym Kazulkin| @VKazulkin |ip.labsGmbH
SnapStartEnabled with DynamoDB Request
Priming
33
https://dev.to/aws-builders/measuring-java-11-lambda-cold-starts-with-snapstart-part-5-priming-end-to-end-latency-and-deployment-time-jem

Vadym Kazulkin| @VKazulkin |ip.labsGmbH
Lambda SnapStart Priming Guide
▪SnapStartPriming guide aims
to explain techniques for
priming Java applications.
▪It assumes a base
understanding of AWS
Lambda, Lambda SnapStart,
and CRaC.
https://github.com/marksailes/snapstart-priming-guide

Vadym Kazulkin| @VKazulkin |ip.labsGmbH
0
500
1000
1500
2000
2500
3000
3500
4000
w/o SnapStart with SnapStart w/o Priming with SnapStart with Priming
Cold starts of Lambda functionwith Java 21 runtime with
1024 MB memory setting, Apache Http Client, compilation
-XX:+TieredCompilation -XX:TieredStopAtLevel=1
p50p75p90p99p99.9max
https://dev.to/aws-builders/aws-snapstart-part-13-measuring-warm-starts-with-java-21-using-different-lambda-memory-settings-160k
ms

Vadym Kazulkin| @VKazulkin |ip.labsGmbH
0,00
5,00
10,00
15,00
20,00
25,00
w/o SnapStart with SnapStart w/o Priming with SnapStart with Priming
Warm starts of Lambda functionwith Java 21 runtimewith
1024 MB memory setting, Apache Http Client compilation -
XX:+TieredCompilation -XX:TieredStopAtLevel=1
p50p75p90p99
https://dev.to/aws-builders/aws-snapstart-part-13-measuring-warm-starts-with-java-21-using-different-lambda-memory-settings-160k
ms

Vadym Kazulkin| @VKazulkin |ip.labsGmbH
0
200
400
600
800
1000
1200
1400
1600
w/o SnapStart with SnapStart w/o Priming with SnapStart with Priming
Warm starts of Lambda functionwith Java 21 runtimewith
1024 MB memory setting, Apache Http Client compilation -
XX:+TieredCompilation -XX:TieredStopAtLevel=1
p99.9max
https://dev.to/aws-builders/aws-snapstart-part-13-measuring-warm-starts-with-java-21-using-different-lambda-memory-settings-160k
ms

Vadym Kazulkin| @VKazulkin |ip.labsGmbH
AWS Lambda Function with Java runtime

Vadym Kazulkin| @VKazulkin |ip.labsGmbH
Product Repository DAO class
39

Vadym Kazulkin| @VKazulkin |ip.labsGmbH
Demo Application
40
https://github.com/Vadym79/AWSLambdaJavaSnapStart
▪Lambda has 1024 MB memory setting
▪Lambda uses x86 architecture
▪Default (Apache) Http Client for
communication with DynamoDB
▪18 MB artifact size, , all dependencies in
the POM file
▪Java compilation option -
XX:+TieredCompilation -
XX:TieredStopAtLevel=1
▪Info about the experiments:
▪Approx. 1 hour duration
▪Approx. first* 100 cold starts
▪Approx. first 100.000 warm starts
*after Lambda function being re-deployed

Vadym Kazulkin| @VKazulkin |ip.labsGmbH
Experiment with:
▪Lambda memory settings
▪Java compilation options
▪HTTP Client implementations (sync and async)
▪Lambda architecture (x86 vs arm64)
▪Lambda SnapStart(with priming techniques)
To find the right trade-off between Lambda cost and performance for your
particular use case
Lambda Performance Tuning Approaches
41
https://aws.amazon.com/de/blogs/developer/preview-release-of-theaws-sdk-java-2-x-http-client-built-on-apache-httpclient-5-5-x/

Vadym Kazulkin| @VKazulkin |ip.labsGmbH
Preview Release of the AWS SDK Java 2.x HTTP Client
built on Apache HttpClient5.5.x
https://aws.amazon.com/de/blogs/developer/preview-release-of-theaws-sdk-java-2-x-http-client-built-on-apache-httpclient-5-5-x/

Vadym Kazulkin| @VKazulkin |ip.labsGmbH
Lambda Deployment Artifact Size
43

Vadym Kazulkin| @VKazulkin |ip.labsGmbH
0
500
1000
1500
2000
2500
3000
3500
4000
4500
w/o SnapStart with SnapStart w/o Priming with SnapStart with Priming
Cold starts of Lambda functionwith Java 21 runtime
using deployment artifact sizes for p90
p90 smallp90 medium p90 big
ms
https://dev.to/aws-builders/aws-snapstart-part-11-measuring-cold-starts-with-java-21-using-different-deployment-artifact-sizes-4g29
▪Small -137 KB (“Hello World”)
▪Medium –14 MB (our sample
application)
▪Big -50 MB (our sample
application + additional
dependencies other to AWS
services)

Vadym Kazulkin| @VKazulkin |ip.labsGmbH
▪Less (dependencies, classes) is more
▪Include only required dependencies (e.g.not the whole AWS SDK 2.0 for Java, but the
dependencies to the clients to be used in Lambda)
▪Exclude dependencies, which you don‘t need at runtime i.e.test frameworks like Junit
Best Practices & Recommendations
45
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>5.4.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>software.amazon.awssdk</groupId>
<artifactId>dynamodb</artifactId>
<version>2.22.2</version>
</dependency>
<dependency>
<groupId>software.amazon.awssdk</groupId>
<artifactId>bom</artifactId>
<version>2.22.2</version>
<type>pom</type>
<scope>import</scope>
</dependency>

Vadym Kazulkin| @VKazulkin |ip.labsGmbH
Demo Application
46
https://github.com/Vadym79/AWSLambdaJavaSnapStart
▪Lambda has 1024 MB memory setting
▪Lambda uses x86 architecture
▪Default (Apache) Http Client for
communication with DynamoDB
▪14 MB artifact size, all dependencies in the
POM file
▪Java compilation option -
XX:+TieredCompilation -
XX:TieredStopAtLevel=1
▪Info about the experiments:
▪Approx. 1 hour duration
▪Approx. first* 100 cold starts
▪Approx. first 100.000 warm starts
*after Lambda function being re-deployed

Vadym Kazulkin| @VKazulkin |ip.labsGmbH
AWS SnapStartDeployment & Invocation
https://docs.aws.amazon.com/lambda/latest/dg/snapstart.html
https://aws.amazon.com/de/blogs/compute/reducing-java-cold-starts-on-aws-lambda-functions-with-snapstart/
•Lambda storesfunction
snapshots in Amazon S3,
dividing them into 512 KB
chunks to optimize
retrieval latency.
•Retrieval latency from
Amazon S3 can take up
to hundreds of
milliseconds for each 512
KB chunk.
•Therefore, Lambda uses
a two-layer cache to
speed-up snapshot
retrieval.

Vadym Kazulkin| @VKazulkin |ip.labsGmbH
Storing snapshots for low-latency retrieval at Lambda
scale
48
https://aws.amazon.com/blogs/compute/under-the-hood-how-aws-lambda-snapstart-optimizes-function-startup-latency/
▪Lambda also maintains a layer one (L1) cache
located on Lambda worker nodes, the (Amazon
EC2) instances handling function invocations.
▪This layer is available locally,thus it provides the
fastest performance, typically 1 millisecond for a
512 KB chunk.
▪Functions with more frequent invocations are
more likely to have their snapshot chunks
cached in this layer.
▪Functions with fewer invocations are
automatically evicted from this cache, because it
is bound by the worker instance disk capacity.
▪When a snapshot chunk is not available in the
L1 cache, Lambda retrieves the chunk from the
L2 cache layer, if not available there from S3.

Vadym Kazulkin| @VKazulkin |ip.labsGmbH
Storing snapshots for low-latency retrieval at Lambda
scale
49
https://aws.amazon.com/blogs/compute/under-the-hood-how-aws-lambda-snapstart-optimizes-function-startup-latency/
▪Resuming execution from snapshots with
low latency is the final SnapStartstage. This
involves loading the retrieved snapshot
chunks into your function execution
environment.
▪Typically, only a subset of the retrieved
snapshot is needed to serve an invocation.
Storing snapshots as chunks lets Lambda
optimize the resume process by proactively
loading only the necessary subset of
chunks.
▪To achieve this, Lambda tracks and records
the snapshot chunks that the function
accesses during each function invocation.

Vadym Kazulkin| @VKazulkin |ip.labsGmbH
Storing snapshots for low-latency retrieval at Lambda
scale
50
https://aws.amazon.com/blogs/compute/under-the-hood-how-aws-lambda-snapstart-optimizes-function-startup-latency/
▪After the first function invocation, Lambda
refers to this recorded chunk access data
for subsequent invokes, as shown in the
following figure.
▪Lambda proactively retrieves and loads this
“working set” of chunks before they are
needed for execution. This significantly
speeds up cold-start latency.

Vadym Kazulkin| @VKazulkin |ip.labsGmbH
▪The speed of restoring a snapshot depends on its contents, size, and the
caching tier used. As a result, SnapStartperformance can vary across
individual functions.
▪Frequently invoked functions are more likely to have their snapshots
cached in the L1 layer, which provides the fastest retrieval latency.
▪Infrequently accessed portions of snapshots for functions with sporadic
invokes are less likely to be present in the L1 layer, resulting in slower
retrieval latency from the L2 and S3 cache layers.
▪Chunk access data for functions with more invocations is also more likely
to be “complete”, which speeds up snapshot restore latency.
SnapStart function performance
https://aws.amazon.com/blogs/compute/under-the-hood-how-aws-lambda-snapstart-optimizes-function-startup-latency/

Vadym Kazulkin| @VKazulkin |ip.labsGmbH
AWS SnapStarttiered cache
52
https://dev.to/aws-builders/aws-snapstart-part-17-impact-of-the-snapshot-tiered-cache-on-the-cold-starts-with-java-21-52ef
•Due to the effect of
snapshot tiered cache, cold
start times reduces with the
number of invocations
•After certain number of
invocations reached the
cold start times becomes
stable

Vadym Kazulkin| @VKazulkin |ip.labsGmbH
AWS Lambda under the Hood
https://www.infoq.com/articles/aws-lambda-under-the-hood/
https://www.infoq.com/presentations/aws-lambda-arch/

Vadym Kazulkin| @VKazulkin |ip.labsGmbH
0
500
1000
1500
2000
2500
with SnapStart w/o Primingwith SnapStart w/o Priming
(last 70)
with SnapStart with
Priming
with SnapStart with
Priming (last 70)
Comparison between all approx.100 vs last 70cold start of the
Lambda function
p50p75p90p99p99.9max
https://dev.to/aws-builders/aws-snapstart-part-17-impact-of-the-snapshot-tiered-cache-on-the-cold-starts-with-java-21-52ef
Due to the effect of
snapshot tiered cache,
cold start times
reduces with the
number of invocations
ms

Vadym Kazulkin| @VKazulkin |ip.labsGmbH
AWS Lambda Profiler Extension for Java
https://github.com/aws/aws-lambda-java-libs/tree/main/experimental/aws-lambda-java-profiler
•The Lambda profiler extension
allows you to profile your Java
functions invoke by invoke, with high
fidelity, and no code changes.
•It uses the async-profilerproject to
produce profiling data and
automatically uploads the data as
HTML flame graphs to S3.

Vadym Kazulkin| @VKazulkin |ip.labsGmbH
AWS Lambda Implementation

Vadym Kazulkin| @VKazulkin |ip.labsGmbH57
https://docs.aws.amazon.com/apigateway/latest/developerguide/set-up-lambda-proxy-integrations.html#api-gateway-simple-proxy-for-lambda-input-format
API Gateway Proxy Request Event JSON

Vadym Kazulkin| @VKazulkin |ip.labsGmbH
AWS Lambda Profiler Extension for Java
https://docs.aws.amazon.com/apigateway/latest/developerguide/set-up-lambda-proxy-integrations.html#api-gateway-simple-proxy-for-lambda-input-format
https://github.com/aws/aws-lambda-java-libs/tree/main/experimental/aws-lambda-java-profiler

Vadym Kazulkin| @VKazulkin |ip.labsGmbH
Full Priming including APIGatewayProxyRequestEvent
Deserialization
https://dev.to/aws-heroes/aws-lambda-profiler-extension-for-java-part-2-improving-lambda-performance-with-lambda-snapstart-4p06
This priming technique leads to up to
25% reduction of the cold start times vs.
DynamoDB request priming alone

Vadym Kazulkin| @VKazulkin |ip.labsGmbH
AWS SnapStart Pricing
60
https://aws.amazon.com/lambda/pricing/?nc1=h_ls

Vadym Kazulkin| @VKazulkin |ip.labsGmbH
▪Avoid saving state that depends on uniqueness during initialization
▪Avoid UUID uniqueSandboxId= UUID.randomUUID() or long envCreationTime
= System.currentTimeMillis() imLambda constructor
▪Use cryptographically secure pseudorandom number generators
▪Software that always gets random numbers from /dev/random or
/dev/urandomalso maintains randomness with SnapStart.
▪Use java.security.SecureRandominstead of new Random()
▪Avoid logic relying on time-based caches
AWS SnapStart Challenges around uniqueness
61
https://docs.aws.amazon.com/lambda/latest/dg/snapstart-uniqueness.html

Vadym Kazulkin| @VKazulkin |ip.labsGmbH
▪SnapStartsupports the Java 11, 17 and 21 (Corretto), Python and .NET
managed runtime only
▪Deployment with SnapStartenabled takes more than 2-2,5 minutes
additionally
▪Snapshot is deleted from cache if Lambda function is not invoked for 14
days
▪SnapStartcurrently does not support :
▪Provisioned concurrency
▪Amazon Elastic File System (Amazon EFS)
▪Ephemeral storage greater than 512 MB
AWS SnapStart Challenges & Limitations
https://docs.aws.amazon.com/lambda/latest/dg/snapstart.html

Vadym Kazulkin| @VKazulkin |ip.labsGmbH63

Vadym Kazulkin| @VKazulkin |ip.labsGmbH
GraalVMArchitecture

Vadym Kazulkin| @VKazulkin |ip.labsGmbH
GraalVMAhead-of-Time Compilation
Source: Oleg Šelajev, Thomas Wuerthinger, Oracle: “Deep dive into using GraalVMfor Java and JavaScript”
https://www.youtube.com/watch?v=a-XEZobXspo

Vadym Kazulkin| @VKazulkin |ip.labsGmbH
AOT vs JIT
Source: „Everything you need to know about GraalVMby Oleg Šelajev& Thomas Wuerthinger” https://www.youtube.com/watch?v=ANN9rxYo5Hg

Vadym Kazulkin| @VKazulkin |ip.labsGmbH
Promise: Java Function compiled into a native executable
using GraalVMNative Imagesignificantly reduces
▪“cold start” times
▪memory footprint
GraalVMNative Image
67

Vadym Kazulkin| @VKazulkin |ip.labsGmbH
▪AWS doesn’t provide GraalVM(Native Image) as Java Runtime out of the box
▪AWS provides Custom Runtime Option
Current Challenges with Native Executable using
GraalVM

Vadym Kazulkin| @VKazulkin |ip.labsGmbH
Custom Lambda Runtimes
https://github.com/Vadym79/AWSLambdaGraalVMNativeImage

Vadym Kazulkin| @VKazulkin |ip.labsGmbH
0
500
1000
1500
2000
2500
3000
3500
4000
w/o SnapStart with SnapStart w/o Primingwith SnapStart with
Priming
GraalVM 23 Native Image
p50p75p90p99p99.9max
https://dev.to/aws-builders/aws-snapstart-part-13-measuring-warm-starts-with-java-21-using-different-lambda-memory-settings-160k
ms

Vadym Kazulkin| @VKazulkin |ip.labsGmbH
0,00
5,00
10,00
15,00
20,00
25,00
w/o SnapStart with SnapStart w/o
Priming
with SnapStart with
Priming
GraalVM 23 Native Image
p50p75p90p99
https://dev.to/aws-builders/aws-snapstart-part-13-measuring-warm-starts-with-java-21-using-different-lambda-memory-settings-160k
ms

Vadym Kazulkin| @VKazulkin |ip.labsGmbH
0
200
400
600
800
1000
1200
1400
1600
w/o SnapStart with SnapStart w/o Primingwith SnapStart with
Priming
GraalVM Native Image 23
p99.9max
https://dev.to/aws-builders/aws-snapstart-part-13-measuring-warm-starts-with-java-21-using-different-lambda-memory-settings-160k
ms

Vadym Kazulkin| @VKazulkin |ip.labsGmbH
Frameworks and libraries Ready for GraalVMNative Image
https://www.graalvm.org/native-image/libraries-and-frameworks/

Vadym Kazulkin| @VKazulkin |ip.labsGmbH
GraalVM Native Image
74
https://github.com/Vadym79/AWSLambdaGraalVMNativeImage/blob/master/pure-lambda-graalvm-jdk-21-native-image/src/main/reflect.json
You can run into runtime errors
(ClassNotFoundExceptions)
when configuration is missing

Vadym Kazulkin| @VKazulkin |ip.labsGmbH
Particulary logging configuration in GraalVM Native
Image is complex
76

Vadym Kazulkin| @VKazulkin |ip.labsGmbH
Log4j natively supports GraalVM Native since 2.0.25
77
https://logging.staged.apache.org/log4j/2.x/graalvm.html

Vadym Kazulkin| @VKazulkin |ip.labsGmbH
Assisted Configuration with GraalVMTracing Agent
https://www.graalvm.org/latest/reference-manual/native-image/metadata/AutomaticMetadataCollection/
https://www.graalvm.org/latest/reference-manual/native-image/guides/configure-with-tracing-agent/
Run the GraalVM tracing
agent during the
execution of your tests

Vadym Kazulkin| @VKazulkin |ip.labsGmbH
▪GraalVMis really powerfuland has a lot of potential
▪GraalVMNative Image improves cold starts and memory footprint
significantly
▪GraalVMNative Image is currently not without challenges
▪Complex GraalVMNative Image configuration files
▪AWS Lambda Custom Runtime requires Linux executable only
▪Building Custom Runtime requires some additional effort
▪e.g.you need a scalable CI/CD pipeline to build memory-intensive native
image
▪Build time is a factor
▪You need to carefully test to avoid runtime errors
GraalVM Conclusion

Vadym Kazulkin| @VKazulkin |ip.labsGmbH
▪With AWS SnapStartand GraalVMNative Image you can reduce cold
start timesof the AWS Lambda with Java 21 runtime to the acceptable
values
▪If you’re willing to accept slightly higher cold and warm start times for
certain the Lambda function(s) and solid priming is applicable -> use fully
managed AWS SnapStartwith priming
▪If a very high performance for certain the Lambda function(s) is really
crucialfor your business -> go for GraalVMNative Image
Wrap up and personal suggestions
80

Vadym Kazulkin| @VKazulkin |ip.labsGmbH
Powertools for AWS Lambda (Java) v2
https://docs.powertools.aws.dev/lambda/java/2.4.0/ https://github.com/Vadym79/AWSPowertoolsForLambdaJavaV2

Vadym Kazulkin| @VKazulkin |ip.labsGmbH
The Future of GraalVM
82
https://blogs.oracle.com/java/post/detaching-graalvm-from-the-java-ecosystem-train

Vadym Kazulkin| @VKazulkin |ip.labsGmbH
Project Leyden
The primary goal of
this Project is to
improve the startup
time, time to peak
performance, and
footprint of Java
programs.
https://www.youtube.com/watch?v=teXijm79vno
https://openjdk.org/projects/leyden/

Vadym Kazulkin| @VKazulkin |ip.labsGmbH
Word of Caution
84
Re-measure for your use case!
Even with my examples measurements might
already produce different results due to:
▪Lambda Amazon CorrettoJava 21 managed
runtime minor version changes
▪Lambda SnapStartsnapshot create and
restore improvements
▪Firecracker microVMimprovements
▪GraalVM(major and minor version) and
Native Image improvements
▪There are still servers behind Lambda
▪Java Memory Model impact (L or RAM
caches hits and misses)
▪Upgrading dependencies (AWS SDK for Java)
tend to make them bigger increasing the
cold start time

Vadym Kazulkin| @VKazulkin |ip.labsGmbH
„AWS Lambda SnapStart „ series
85
https://dev.to/vkazulkin/series/24979
Article series covers the why and
what behind Lambda SnapStart
and priming techniques including
measurements for the cold and
warm starts with different
settings for:
▪Java 11
▪Java 17
▪Java 21

Vadym Kazulkin| @VKazulkin |ip.labsGmbH
“Spring Boot 3.4/ Quarkus3/ Micronaut 4 application
on AWS Lambda” series
86
Article series covers different
ways to write, run and optimize
Spring Boot 3.4 / Quarkus3 /
Micronaut 4 applications on AWS
Lambda using:
▪Managed Java 21 Lambda
runtime + SnapStart+ priming
▪GraalVMNative Image
Cold and warm start time
measurements are also provided
https://dev.to/vkazulkin/series/30408 https://dev.to/vkazulkin/series/31519 https://dev.to/vkazulkin/series/26067

Vadym Kazulkin| @VKazulkin |ip.labsGmbH
“Data API for Amazon Aurora Serverless v2 with AWS
SDK for Java” series
87
Article series covers pure
Java 21 cold and warm
start time measurements
and optimization
techniques for Amazon
Aurora Serverless v2
database with JDBC and
Data API
https://dev.to/vkazulkin/series/26067

Vadym Kazulkin| @VKazulkin |ip.labsGmbH
“Serverless applications with Java and Aurora DSQL” series
https://dev.to/vkazulkin/series/32326
Article series covers pure
Java 21 cold and warm
start time measurements
and optimization
techniques
(SnapStart+primingvs
GraalVMNative Image)
for Amazon Aurora DSQL
database

Vadym Kazulkin| @VKazulkin |ip.labsGmbH
Thank you