How to develop, run and optimize Spring Boot 3 application on AWS Lambda at JUG Bonn 2024

VadymKazulkin 32 views 134 slides Aug 24, 2024
Slide 1
Slide 1 of 134
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
Slide 88
88
Slide 89
89
Slide 90
90
Slide 91
91
Slide 92
92
Slide 93
93
Slide 94
94
Slide 95
95
Slide 96
96
Slide 97
97
Slide 98
98
Slide 99
99
Slide 100
100
Slide 101
101
Slide 102
102
Slide 103
103
Slide 104
104
Slide 105
105
Slide 106
106
Slide 107
107
Slide 108
108
Slide 109
109
Slide 110
110
Slide 111
111
Slide 112
112
Slide 113
113
Slide 114
114
Slide 115
115
Slide 116
116
Slide 117
117
Slide 118
118
Slide 119
119
Slide 120
120
Slide 121
121
Slide 122
122
Slide 123
123
Slide 124
124
Slide 125
125
Slide 126
126
Slide 127
127
Slide 128
128
Slide 129
129
Slide 130
130
Slide 131
131
Slide 132
132
Slide 133
133
Slide 134
134

About This Presentation

In this talk I will present and compare several options of how to run Spring Boot 3 application on AWS Lambda using:

AWS Serverless Java Container
AWS Lambda Web Adapter
Spring Cloud Function and
Custom Docker Image.

I'll also discuss strategies how to optimize cold start of such Lambda functi...


Slide Content

Vadym Kazulkin| @VKazulkin |ip.labsGmbH
How to develop, run and optimize Spring Boot 3
application on AWS Lambda
Vadym Kazulkin, ip.labs, Java User Group Bonn, 21 August 2024
How to develop,
run and optimize
Spring Boot 3
application on
1

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
About ip.labs
How to develop, run and optimize Spring Boot 3 application on AWS Lambda4

Vadym Kazulkin| @VKazulkin |ip.labsGmbH
▪Your organization has profound Java and Spring Boot development skills
▪You have an existing Spring Boot 3 (Web) application, or you want to develop
a new one
Current State
How to develop, run and optimize Spring Boot 3 application on AWS Lambda7

Vadym Kazulkin| @VKazulkin |ip.labsGmbH
▪You want to use AWS Lambda for hosting your Spring Boot 3 web application
▪To benefit from the advantages of the Serverless architectures
▪Scalability
▪Less focus on classical operational tasks
▪API Gateway and Lambda offer fully managed approach
▪Less focus on the code maintenance
▪Requires securing the application only
Desired State
How to develop, run and optimize Spring Boot 3 application on AWS Lambda8

Vadym Kazulkin| @VKazulkin |ip.labsGmbH
▪I can at best achieve acceptable performance by using pure Java on AWS Lambda
▪Spring (Boot) performance on AWS Lambda would bebad
▪Too much runtime annotation processing, reflection, dynamic class loading used
▪As a result,high cold (application start up) and warm start times
Most frequentreplies and assumptions
How to develop, run and optimize Spring Boot 3 application on AWS Lambda9

Vadym Kazulkin| @VKazulkin |ip.labsGmbH
▪I’ll use NoSQL Amazon DynamoDB for my examples
▪You can make it work with the same introduced approaches by
managing your own database or using Amazon RDS (i.e. PostgreSQL)
▪Challenges around managing database connection. Possible solutions are:
▪Using Amazon RDS Proxy and putting Lambda functions into VPC
▪Using (PostgreSQL) Aurora Serverless v2 Data API
▪You need to re-measure performance
Database usage
How to develop, run and optimize Spring Boot 3 application on AWS Lambda10

Vadym Kazulkin| @VKazulkin |ip.labsGmbH
Demo Application
How to develop, run and optimize Spring Boot 3 application on AWS Lambda12
https://github.com/Vadym79/AWSLambdaJavaWithSpringBoot
▪PUT
https://{YOUR_API_GATEWAY_URL}/prod
/products/
▪GET
https://{YOUR_API_GATEWAY_URL}/prod
/products/ {productId}

Vadym Kazulkin| @VKazulkin |ip.labsGmbH
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
Spring Boot 3 Application class
How to develop, run and optimize Spring Boot 3 application on AWS Lambda13
https://github.com/Vadym79/AWSLambdaJavaSnapStart/tree/main/spring-boot-3.2

Vadym Kazulkin| @VKazulkin |ip.labsGmbH
public record Product(String id, String name, BigDecimalprice) { }
Product Entity class
How to develop, run and optimize Spring Boot 3 application on AWS Lambda14
https://github.com/Vadym79/AWSLambdaJavaSnapStart/tree/main/spring-boot-3.2

Vadym Kazulkin| @VKazulkin |ip.labsGmbH
@Repository
public class DynamoProductDaoimplements ProductDao{
private static final String PRODUCT_TABLE_NAME =
System.getenv("PRODUCT_TABLE_NAME");
private static final DynamoDbClientdynamoDbClient=
DynamoDbClient.builder().build();
@Override
public void putProduct(Product product) {
dynamoDbClient.putItem(PutItemRequest.builder()
.tableName(PRODUCT_TABLE_NAME)
.item(ProductMapper.productToDynamoDb(product))
.build());
}
Product Repository DAO class
How to develop, run and optimize Spring Boot 3 application on AWS Lambda15
https://github.com/Vadym79/AWSLambdaJavaSnapStart/tree/main/spring-boot-3.2

Vadym Kazulkin| @VKazulkin |ip.labsGmbH
@Override
public Optional<Product> getProduct(String id) {
GetItemResponsegetItemResponse=
dynamoDbClient.getItem(GetItemRequest.builder().key(Map.of("PK",
AttributeValue.builder().s(id).build())).tableName(PRODUCT_TABLE_NAME).build())
;
if (getItemResponse.hasItem()) {
return
Optional.of(ProductMapper.productFromDynamoDB(getItemResponse.item()));
} else {
return Optional.empty();
}
}
..
}
Product Repository DAO class
How to develop, run and optimize Spring Boot 3 application on AWS Lambda16
https://github.com/Vadym79/AWSLambdaJavaSnapStart/tree/main/spring-boot-3.2

Vadym Kazulkin| @VKazulkin |ip.labsGmbH
▪AWS Serverless Java Container
▪AWS Lambda Web Adapter
▪Spring Cloud Function (on AWS Lambda)
▪Custom (Docker) Container Image
▪Optimization techniques
▪AWS (Lambda) SnapStart
▪GraalVMNative Image
▪Cold and warm start measurements for all approaches and optimizations
Agenda
How to develop, run and optimize Spring Boot 3 application on AWS Lambda17

Vadym Kazulkin| @VKazulkin |ip.labsGmbH
AWS Serverless Java Container
How to develop, run and optimize Spring Boot 3 application on AWS Lambda18
https://github.com/aws/serverless-java-container/

Vadym Kazulkin| @VKazulkin |ip.labsGmbH
▪The AWS Serverless Java Container makes it
easier to run Java applications written with
frameworks such as Struts, Spring, Spring Boot
2 and 3, or JAX-RS/Jersey in Lambda.
▪The container provides adapter logic to
minimize code changes. Incoming events are
translated to the Jakarta EE Servlet specification
so that frameworks work as before
AWS Serverless Java Container
How to develop, run and optimize Spring Boot 3 application on AWS Lambda19
https://github.com/aws/serverless-java-container/

Vadym Kazulkin| @VKazulkin |ip.labsGmbH
pom.xml
<dependency>
<groupId>com.amazonaws.serverless</groupId>
<artifactId>aws-serverless-java-container-springboot3</artifactId>
<version>2.0.0</version>
</dependency>
AWS Serverless Java Container
How to develop, run and optimize Spring Boot 3 application on AWS Lambda20
https://github.com/Vadym79/AWSLambdaJavaSnapStart/tree/main/spring-boot-3.2

Vadym Kazulkin| @VKazulkin |ip.labsGmbH
@RestController @EnableWebMvc
public class ProductController{
@Autowired
private DynamoProductDaoproductDao;
@RequestMapping(path = “/products/{id}”, method = RequestMethod.GET, produces =
MediaType.APPLICATION_JSON_VALUE)
public Optional<Product> getProductById(@PathVariable(“id”) String id) {
return productDao.getProduct(id);
}
@RequestMapping(path = “/products”, method = RequestMethod.PUT, consumes =
MediaType.APPLICATION_JSON_VALUE)
public void createProduct(@RequestBody Product product) {
productDao.putProduct(product);
}
Spring Boot 3 Product (Rest)Controller class
How to develop, run and optimize Spring Boot 3 application on AWS Lambda21
https://github.com/Vadym79/AWSLambdaJavaSnapStart/tree/main/spring-boot-3.2

Vadym Kazulkin| @VKazulkin |ip.labsGmbH
@RequestMapping(path = “/products/{id}”, method = RequestMethod.GET, produces =
MediaType.APPLICATION_JSON_VALUE)
public Optional<Product> getProductById(@PathVariable(“id”) String id) {
return productDao.getProduct(id);
}
Mappsto the Lambda function in IaC(AWS SAM template)
GetProductByIdFunction:
Type: AWS::Serverless::Function
....
Events:
GetRequestById:
Type: Api
Properties:
RestApiId: !Ref MyApi
Path: /products/{id}
Method: get
Spring Boot 3 Rest Controller method mapping to
Lambda Function in IaC
How to develop, run and optimize Spring Boot 3 application on AWS Lambda22

Vadym Kazulkin| @VKazulkin |ip.labsGmbH
Automatic proxying through AWS Serverless Java Container
AWS SAM Template (template.yaml)
GetProductByIdFunction:
Type: AWS::Serverless::Function
Properties:
Handler: com.amazonaws.serverless.proxy.spring.SpringDelegatingLambdaContainerHandler
CodeUri: target/***.jar
Runtime: java21
MemorySize: 1024
Environment:
Variables:
MAIN_CLASS: com.amazonaws.serverless.sample.springboot3.Application
AWS Serverless Java Container
How to develop, run and optimize Spring Boot 3 application on AWS Lambda24
https://github.com/Vadym79/AWSLambdaJavaSnapStart/tree/main/spring-boot-3.2
Use generic AWS Serverless Container
Spring Boot 3 proxy Lambda function

Vadym Kazulkin| @VKazulkin |ip.labsGmbH
Self-written Lambda function
AWS SAM Template (template.yaml)
GetProductByIdFunction:
Type: AWS::Serverless::Function
Properties:
Handler: software.amazonaws.example.product.handler.StreamLambdaHandler::handleRequest
CodeUri: target/***.jar
Runtime: java21
MemorySize: 1024

AWS Serverless Java Container
How to develop, run and optimize Spring Boot 3 application on AWS Lambda25
https://github.com/Vadym79/AWSLambdaJavaSnapStart/tree/main/spring-boot-3.2
Or implement our own Lambda function
as an alternative

Vadym Kazulkin| @VKazulkin |ip.labsGmbH
public class StreamLambdaHandlerimplements RequestStreamHandler{
SpringBootLambdaContainerHandler<AwsProxyRequest, AwsProxyResponse> handler =
SpringBootLambdaContainerHandler.getAwsProxyHandler(Application.class);
@Override
public void handleRequest(InputStreaminputStream, OutputStreamoutputStream, Context
context) throws IOException{
handler.proxyStream(inputStream, outputStream, context);
}
}
AWS Serverless Java Container
How to develop, run and optimize Spring Boot 3 application on AWS Lambda26
https://github.com/Vadym79/AWSLambdaJavaSnapStart/tree/main/spring-boot-3.2

Vadym Kazulkin| @VKazulkin |ip.labsGmbH
AWS Lambda Web Adapter
How to develop, run and optimize Spring Boot 3 application on AWS Lambda27
https://github.com/awslabs/aws-lambda-web-adapter

Vadym Kazulkin| @VKazulkin |ip.labsGmbH
▪AWS Lambda Web Adapter is a tool written in Rust programming language
to run web applications on AWS Lambda.
▪It allows developers to build web apps (HTTP API) with familiar frameworks
(e.g. Express.js, Next.js, Flask, Spring Boot, ASP.NET and Laravel, anything
that speaks HTTP 1.1/1.0) and run it on AWS Lambda.
▪The same Docker image can run also on Amazon EC2, AWS Fargate, and
local computers
AWS Lambda Web Adapter
How to develop, run and optimize Spring Boot 3 application on AWS Lambda28
https://github.com/awslabs/aws-lambda-web-adapter

Vadym Kazulkin| @VKazulkin |ip.labsGmbH
▪Run web applications on AWS Lambda
▪Supports Amazon API Gateway Rest API and HTTP
API endpoints, Lambda Function URLs, and
Application Load Balancer
▪Supports all non-HTTP event triggers, such as SQS,
SNS, S3, DynamoDB, Kinesis, Kafka, EventBridge,
and Bedrock Agents
AWS Lambda Web Adapter
How to develop, run and optimize Spring Boot 3 application on AWS Lambda29
https://github.com/awslabs/aws-lambda-web-adapter

Vadym Kazulkin| @VKazulkin |ip.labsGmbH
Can be deployed in several ways:
▪Lambda functions packaged as Docker Images
▪Lambda functions packaged as OCI Images
▪Lambda functions packaged as Zip package for
AWS managed runtimesand attached as Lambda
layer to your Lambda function
AWS Lambda Web Adapter
How to develop, run and optimize Spring Boot 3 application on AWS Lambda30
https://github.com/awslabs/aws-lambda-web-adapter

Vadym Kazulkin| @VKazulkin |ip.labsGmbH
@RestController @EnableWebMvc
public class ProductController{
@Autowired
private DynamoProductDaoproductDao;
@RequestMapping(path = “/products/{id}”, method = RequestMethod.GET, produces =
MediaType.APPLICATION_JSON_VALUE)
public Optional<Product> getProductById(@PathVariable(“id”) String id) {
return productDao.getProduct(id);
}
@RequestMapping(path = “/products”, method = RequestMethod.PUT, consumes =
MediaType.APPLICATION_JSON_VALUE)
public void createProduct(@RequestBody Product product) {
productDao.putProduct(product);
}
Spring Boot 3 Product (Rest)Controller class
How to develop, run and optimize Spring Boot 3 application on AWS Lambda31
https://github.com/Vadym79/AWSLambdaJavaSnapStart/tree/main/spring-boot-3.2

Vadym Kazulkin| @VKazulkin |ip.labsGmbH
@RequestMapping(path = “/products/{id}”, method = RequestMethod.GET, produces =
MediaType.APPLICATION_JSON_VALUE)
public Optional<Product> getProductById(@PathVariable(“id”) String id) {
return productDao.getProduct(id);
}
Mappsto the Lambda function in IaC(AWS SAM template)
GetProductByIdFunction:
Type: AWS::Serverless::Function
....
Events:
GetRequestById:
Type: Api
Properties:
RestApiId: !Ref MyApi
Path: /products/{id}
Method: get
Spring Boot 3 Rest Controller method mapping to
Lambda Function in IaC
How to develop, run and optimize Spring Boot 3 application on AWS Lambda32

Vadym Kazulkin| @VKazulkin |ip.labsGmbH
AWS SAM Template (template.yaml)
GetProductByIdFunction:
Type: AWS::Serverless::Function
Properties:
Handler: run.sh
CodeUri: target/***.jar
Runtime: java21
MemorySize: 1024
Layers:
- !Sub arn:aws:lambda:${AWS::Region}:753240598075:layer:LambdaAdapterLayerX86:20
Environment:
Variables:
AWS_LAMBDA_EXEC_WRAPPER: /opt/bootstrap
AWS Lambda Web Adapter
How to develop, run and optimize Spring Boot 3 application on AWS Lambda34
https://github.com/Vadym79/AWSLambdaJavaWithSpringBoot/tree/master/spring-boot-3.2-with-lambda-web-adapter

Vadym Kazulkin| @VKazulkin |ip.labsGmbH
run.sh
#!/bin/sh
exec java -cp "./:lib/*" "software.amazonaws.Application"
AWS Lambda Web Adapter
How to develop, run and optimize Spring Boot 3 application on AWS Lambda35
https://github.com/Vadym79/AWSLambdaJavaWithSpringBoot/tree/master/spring-boot-3.2-with-lambda-web-adapter

Vadym Kazulkin| @VKazulkin |ip.labsGmbH
AWS SAM Template (template.yaml)
GetProductByIdFunction:
Type: AWS::Serverless::Function
Properties:
Handler: run.sh
CodeUri: target/***.jar
Runtime: java21
MemorySize: 1024
Layers:
- !Sub arn:aws:lambda:${AWS::Region}:753240598075:layer:LambdaAdapterLayerX86:20
Environment:
Variables:
AWS_LAMBDA_EXEC_WRAPPER: /opt/bootstrap
AWS Lambda Web Adapter
How to develop, run and optimize Spring Boot 3 application on AWS Lambda36
https://github.com/Vadym79/AWSLambdaJavaWithSpringBoot/tree/master/spring-boot-3.2-with-lambda-web-adapter

Vadym Kazulkin| @VKazulkin |ip.labsGmbH
Spring Cloud Function for AWS Lambda
How to develop, run and optimize Spring Boot 3 application on AWS Lambda38
https://spring.io/projects/spring-cloud-function https://spring.io/projects/spring-cloud-aws

Vadym Kazulkin| @VKazulkin |ip.labsGmbH
▪Promote the implementation of business logic via functions.
▪A simple function application (in context or Spring) is an application that
contains beans of type Supplier, Java 8 Function interfaceor Consumer.
Spring Cloud Function for AWS Lambda
How to develop, run and optimize Spring Boot 3 application on AWS Lambda39
https://spring.io/projects/spring-cloud-function https://spring.io/projects/spring-cloud-aws

Vadym Kazulkin| @VKazulkin |ip.labsGmbH
▪With Spring Cloud Function on AWS Lambda, AWS adapter takes a Spring
Cloud Functionapp and converts it to a form that can run in AWS Lambda
▪With AWS it means that a simple function bean should be recognized and
executed in AWS Lambda environment
▪Fits well into the AWS Lambda model with Amazon API Gateway in front
which similar to the Java 8 function receives the (HTTP) request, executes
some business logic and then sends the (HTTP) response to the caller
Spring Cloud Function for AWS Lambda
How to develop, run and optimize Spring Boot 3 application on AWS Lambda41
https://spring.io/projects/spring-cloud-function https://spring.io/projects/spring-cloud-aws

Vadym Kazulkin| @VKazulkin |ip.labsGmbH
▪AWS Request Adapter converts the JSON coming
from Lambda function to the HttpServletRequest
which then invokes the Spring Dispatcher Servlet
which then interacts with our Spring Boot
application on API level without starting web server
▪Then response flows back and AWS Response
Adapter converts HttpServletResponseto JSON
which Lambda function sends back to API Gateway.
Spring Cloud Function for AWS Lambda
How to develop, run and optimize Spring Boot 3 application on AWS Lambda42
https://spring.io/projects/spring-cloud-function https://spring.io/projects/spring-cloud-aws

Vadym Kazulkin| @VKazulkin |ip.labsGmbH
pom.xml
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-function-adapter-aws</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-function-web</artifactId>
</dependency>
Spring Cloud Function for AWS Lambda
How to develop, run and optimize Spring Boot 3 application on AWS Lambda44
https://github.com/Vadym79/AWSLambdaJavaWithSpringBoot/tree/master/spring-boot-3.2-with-spring-cloud-function

Vadym Kazulkin| @VKazulkin |ip.labsGmbH
AWS SAM Template (template.yaml)
GetProductByIdFunction:
Type: AWS::Serverless::Function
Properties:
Handler: org.springframework.cloud.function.adapter.aws.FunctionInvoker::handleRequest
CodeUri: target/***.jar
Runtime: java21
MemorySize: 1024
Environment:
Variables:
MAIN_CLASS: software.amazonaws.Application
SPRING_CLOUD_FUNCTION_DEFINITION: getProductByIdHandler
Spring Cloud Function for AWS Lambda
How to develop, run and optimize Spring Boot 3 application on AWS Lambda45
https://github.com/Vadym79/AWSLambdaJavaWithSpringBoot/tree/master/spring-boot-3.2-with-spring-cloud-function

Vadym Kazulkin| @VKazulkin |ip.labsGmbH
@Component
public class GetProductByIdHandlerimplements
Function<APIGatewayProxyRequestEvent, Product> {
@Autowired
private DynamoProductDaoproductDao;
...
public APIGatewayProxyResponseEventapply(APIGatewayProxyRequestEventrequestEvent) {
String id = requestEvent.getPathParameters().get("id");
return productDao.getProduct(id);
}
Spring Cloud Function for AWS Lambda
How to develop, run and optimize Spring Boot 3 application on AWS Lambda46
https://github.com/Vadym79/AWSLambdaJavaWithSpringBoot/tree/master/spring-boot-3.2-with-spring-cloud-function
SPRING_CLOUD_FUNCTION_DEFINITION:
getProductByIdHandler

Vadym Kazulkin| @VKazulkin |ip.labsGmbH
Docker Image with Spring Cloud Function
for AWS Lambda
How to develop, run and optimize Spring Boot 3 application on AWS Lambda47

Vadym Kazulkin| @VKazulkin |ip.labsGmbH
▪Re-use Spring Cloud Function
▪Use Base Java 21 Docker Image from Amazon ECR
public.ecr.aws/lambda/java:21
▪Docker build image
▪Docker tag image
▪Create Amazon ECR repository (if not exists)
▪Docker push image to Amazon ECR repository
Docker Container Image with Spring Cloud Function
How to develop, run and optimize Spring Boot 3 application on AWS Lambda48
https://github.com/Vadym79/AWSLambdaJavaDockerImage/

Vadym Kazulkin| @VKazulkin |ip.labsGmbH
Dockerfile
FROM public.ecr.aws/lambda/java:21
# Copy function code and runtime dependencies from Maven layout
COPY target/classes ${LAMBDA_TASK_ROOT}
COPY target/dependency/* ${LAMBDA_TASK_ROOT}/lib/
Docker Container Image with Spring Cloud Function
How to develop, run and optimize Spring Boot 3 application on AWS Lambda49
https://github.com/Vadym79/AWSLambdaJavaDockerImage/

Vadym Kazulkin| @VKazulkin |ip.labsGmbH
AWS SAM Template (template.yaml)
GetProductByIdFunction:
Type: AWS::Serverless::Function
Properties:
PackageType: Image
ImageUri: !Sub ${AWS::AccountId}.dkr.ecr.eu-central-1.amazonaws.com/aws-spring-boot-
3.2-java21-custom-docker-image:v1
ImageConfig:
Command:
["org.springframework.cloud.function.adapter.aws.FunctionInvoker::handleRequest"]
MemorySize: 1024
Environment:
Variables:
MAIN_CLASS: software.amazonaws.Application
SPRING_CLOUD_FUNCTION_DEFINITION: getProductByIdHandler
Docker Container Image with Spring Cloud Function
How to develop, run and optimize Spring Boot 3 application on AWS Lambda50
https://github.com/Vadym79/AWSLambdaJavaDockerImage/

Vadym Kazulkin| @VKazulkin |ip.labsGmbH
Demo Application
How to develop, run and optimize Spring Boot 3 application on AWS Lambda51
https://github.com/Vadym79/AWSLambdaJavaWithSpringBoot
▪Used Spring 3.2 with Amazon Corretto
Java 21
▪Lambda has 1024 MB memory setting
▪Lambda uses x86 architecture
▪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
Lambda function lifecycle –a full cold start
How to develop, run and optimize Spring Boot 3 application on AWS Lambda52
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
▪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 kicks in
▪Init-phase has full CPU access up to 10 seconds for free for the managed execution
environments)
▪Lambda invokes the handler method
How to develop, run and optimize Spring Boot 3 application on AWS Lambda53
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
0
1000
2000
3000
4000
5000
6000
7000
8000
AWS Serverless Java
Container
AWS Lambda Web AdapterSpring Cloud Function for
AWS
Docker Image based on
Spring Cloud Function for
AWS
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
1000
2000
3000
4000
5000
6000
7000
8000
AWS Serverless Java
Container
AWS Lambda Web
Adapter
Spring Cloud
Function for AWS
Docker Image based
on Spring Cloud
Function for AWS
Pure Java w/o
framework usage
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
30,00
AWS Serverless Java
Container
AWS Lambda Web AdapterSpring Cloud Function for
AWS
Docker Image based on
Spring Cloud Function for
AWS
p50p75p90p99
ms

Vadym Kazulkin| @VKazulkin |ip.labsGmbH
0,00
5,00
10,00
15,00
20,00
25,00
30,00
AWS Serverless Java
Container
AWS Lambda Web
Adapter
Spring Cloud
Function for AWS
Docker Image based
on Spring Cloud
Function for AWS
Pure Java w/o
framework usage
p50p75p90p99
ms

Vadym Kazulkin| @VKazulkin |ip.labsGmbH
0
500
1000
1500
2000
2500
AWS Serverless Java
Container
AWS Lambda Web AdapterSpring Cloud Function for
AWS
Docker Image based on
Spring Cloud Function for
AWS
p99.9max
ms

Vadym Kazulkin| @VKazulkin |ip.labsGmbH
0
500
1000
1500
2000
2500
AWS Serverless Java
Container
AWS Lambda Web
Adapter
Spring Cloud
Function for AWS
Docker Image based
on Spring Cloud
Function for AWS
Pure Java w/o
framework usage
p99.9max
ms

Vadym Kazulkin| @VKazulkin |ip.labsGmbH
Latency is the amount of time it takes from when a request
is made by the user to the time it takes for the response to
get back to that user
Latency
How to develop, run and optimize Spring Boot 3 application on AWS Lambda63

Vadym Kazulkin| @VKazulkin |ip.labsGmbH
For our application:
Overall latency =
t(client to create and send request to the API Gateway endpoint) +
t(API Gateway to process request and invoke Lambda function) +
t(Lambda cold start time)+
t(Lambda warm start time) +
t(API Gateway to processes Lambda response and sends it back to the client) +
t(client to receive and process response from the API Gateway endpoint)
Latency
How to develop, run and optimize Spring Boot 3 application on AWS Lambda64
involves DNS resolve
and SSL handshake

Vadym Kazulkin| @VKazulkin |ip.labsGmbH
AWS Lambda
SnapStart
65 How to develop, run and optimize Spring Boot 3 application on AWS Lambda

Vadym Kazulkin| @VKazulkin |ip.labsGmbH
AWS Lambda SnapStart!= SnapChat
AWS Lambda SnapStart
How to develop, run and optimize Spring Boot 3 application on AWS Lambda66
https://docs.aws.amazon.com/lambda/latest/dg/snapstart.html

Vadym Kazulkin| @VKazulkin |ip.labsGmbH
AWS People behind Amazon Corretto
High performance Serverless Java on AWS67

Vadym Kazulkin| @VKazulkin |ip.labsGmbH
„AWS Lambda SnapStart „ series
How to develop, run and optimize Spring Boot 3 application on AWS Lambda68
https://dev.to/vkazulkin/measuring-java-11-lambda-cold-starts-with-snapstart-part-1-first-impressions-30a4
Article series covers they why and what
behind Lambda SnapStartand priming
techniques including measurements for cold
and warm starts with different settings for
▪Java 11
▪Java 17
▪Java 21
▪Micronaut
▪Quarkus
▪Spring Boot 2.7

Vadym Kazulkin| @VKazulkin |ip.labsGmbH
▪Lambda SnapStartfor Java can improve startup performance for latency-
sensitive applications
▪SnapStartis fully managed
AWS Lambda SnapStart
How to develop, run and optimize Spring Boot 3 application on AWS Lambda69
https://docs.aws.amazon.com/lambda/latest/dg/snapstart.html

Vadym Kazulkin| @VKazulkin |ip.labsGmbH
AWS SnapStartDeployment & Invocation
How to develop, run and optimize Spring Boot 3 application on AWS Lambda70
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
▪Currently available for Lambda managed Java Runtimes (Java 11, 17 and 21)
▪Not available for all other Lambda runtimes:
▪Docker Container Image
▪Custom (Lambda) Runtime (a way to ship GraalVMNative Image)
AWS Lambda SnapStart
How to develop, run and optimize Spring Boot 3 application on AWS Lambda71
https://github.com/Vadym79/AWSLambdaJavaDockerImage/

Vadym Kazulkin| @VKazulkin |ip.labsGmbH
available for:
▪AWS Serverless Java Container
▪AWS Lambda Web Adapter
▪Spring Cloud Function (on AWS Lambda)
▪Custom (Docker) Container Image
AWS Lambda SnapStart
How to develop, run and optimize Spring Boot 3 application on AWS Lambda72

Vadym Kazulkin| @VKazulkin |ip.labsGmbH
AWS SnapStartDeployment & Invocation
How to develop, run and optimize Spring Boot 3 application on AWS Lambda74
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
How to develop, run and optimize Spring Boot 3 application on AWS Lambda75
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/
Firecracker microVM
create & restore
snapshot

Vadym Kazulkin| @VKazulkin |ip.labsGmbH
▪Linux CRIU available since 2012 allows a running application to be paused and restarted at some
point later in time, potentially on a different machine.
▪The overall goal of the project is to support the migration of containers.
▪When performing a checkpoint, essentially, the full context of the process is saved: program
counter, registers, stacks, memory-mapped and shared memory
▪To restore the application, all this data can be reloaded and (theoretically) it continues from the
same point.
▪Challenges
▪open files
▪network connections
▪sudden change in the value of the system clock
▪time-based caches
CRIU (Checkpoint/Restore in Userspace)
How to develop, run and optimize Spring Boot 3 application on AWS Lambda76
https://criu.org/Main_Page

Vadym Kazulkin| @VKazulkin |ip.labsGmbH
▪Comparing Firecracker and CRIU snapshotting:
▪Firecracker snapshotting saves a whole running OS
▪CRIU snapshotting saves a single process or container
▪Advantagesof the Firecracker snapshot : we don't have to care about
file handles because they will be still valid after resume.
▪Drawbacksthe Firecracker snapshot : the need to reseed /dev/random
and to sync the system clock.
Snapshot /checkpointing and restore
Firecracker microVMvs CRIU
High performance Serverless Java on AWS77
https://mail.openjdk.org/pipermail/discuss/2021-July/005864.html

Vadym Kazulkin| @VKazulkin |ip.labsGmbH
▪CRaCis a JDK project that allows you to start Java programs with a
shorter time to first transaction, combined with less time and resources
to achieve full code speed.
▪CRaCeffectively takes a snapshot of the Java process (checkpoint) when
it is fully warmed up, then uses that snapshot to launch any number of
JVMs from this captured state.
▪CRaCis based on CRIU
Ideas behind CRaC(Coordinated Restore at
Checkpoint)
How to develop, run and optimize Spring Boot 3 application on AWS Lambda81
https://www.azul.com/blog/superfast-application-startup-java-on-crac/ https://github.com/CRaC/docs

Vadym Kazulkin| @VKazulkin |ip.labsGmbH
AWS SnapStartDeployment & Invocation
How to develop, run and optimize Spring Boot 3 application on AWS Lambda82
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
AWS Lambda SnapStartwith Priming
How to develop, run and optimize Spring Boot 3 application on AWS Lambda83

Vadym Kazulkin| @VKazulkin |ip.labsGmbH
AWS Lambda SnapStartwith Priming
Approach 1 Priming of DynamoDBrequest
How to develop, run and optimize Spring Boot 3 application on AWS Lambda85

Vadym Kazulkin| @VKazulkin |ip.labsGmbH
▪Primedependencies during initialization phase (when it worth doing)
▪„Fake“ the calls to pre-initialize „some other expensive stuff“ (this technique is called
Priming)
▪In case of DynamoDB client put the following code outside of the handler method to
pre-initialize the HTTP Client and Jackson Marshaller:
DynamoDbClientclient = DynamoDbClientBuilder.builder().region(Regions.US_WEST_2).build();
GetItemResponse getItemResponse = client.getItem(GetItemRequest.builder()
.key(Map.of("PK", AttributeValue.builder().s(id).build()))
.tableName(PRODUCT_TABLE_NAME).build());
……
Priming
How to develop, run and optimize Spring Boot 3 application on AWS Lambda86
invocation forces HTTP Client and Jackson
Marshallers to pre-initialize
getProductById (int id)
method

Vadym Kazulkin| @VKazulkin |ip.labsGmbH
@Configuration
public class Priming implements Resource{
@Autowired
private DynamoProductDaoproductDao;
public Priming() {
Core.getGlobalContext().register(this);
}
@Override
public void beforeCheckpoint(Context<? extends Resource> context) throws Exception {
productDao.getProduct("0");
}
@Override
public void afterRestore(Context<? extends Resource> context) throws Exception { }
}
AWS Serverless Java Container (Priming of DynamoDB request)
How to develop, run and optimize Spring Boot 3 application on AWS Lambda87
Applies priming to all Lambda functions
in the deployment artifact

Vadym Kazulkin| @VKazulkin |ip.labsGmbH
public class StreamLambdaHandlerimplements RequestStreamHandler, Resource{
SpringBootLambdaContainerHandler<AwsProxyRequest, AwsProxyResponse> handler =
SpringBootLambdaContainerHandler.getAwsProxyHandler(Application.class);
@Autowired
private DynamoProductDaoproductDao;
public StreamLambdaHandler() {
Core.getGlobalContext().register(this);
}
@Override
public void handleRequest(InputStreaminputStream, OutputStreamoutputStream, Context context) {
handler.proxyStream(inputStream, outputStream, context);
}
How to develop, run and optimize Spring Boot 3 application on AWS Lambda88
AWS Serverless Java Container (Priming of DynamoDB request)
Another alternative to apply
priming only for certain Lambda
function(s)

Vadym Kazulkin| @VKazulkin |ip.labsGmbH
@Override
public void beforeCheckpoint(Context<? extends Resource> context) throws Exception {
productDao.getProduct("0");
}
@Override
public void afterRestore(Context<? extends Resource> context) throws Exception { }
}
How to develop, run and optimize Spring Boot 3 application on AWS Lambda89
AWS Serverless Java Container (Priming of DynamoDB request)

Vadym Kazulkin| @VKazulkin |ip.labsGmbH
@Configuration
public class Priming implements Resource{
@Autowired
private DynamoProductDaoproductDao;
public Priming() {
Core.getGlobalContext().register(this);
}
@Override
public void beforeCheckpoint(Context<? extends Resource> context) throws Exception {
productDao.getProduct("0");
}
@Override
public void afterRestore(Context<? extends Resource> context) throws Exception { }
}
AWS Lambda Web Adapter (Priming of DynamoDB request)
How to develop, run and optimize Spring Boot 3 application on AWS Lambda90
Looks the same as with AWS
Serverless Java Container

Vadym Kazulkin| @VKazulkin |ip.labsGmbH
@Component
public class GetProductByIdHandlerimplements
Function<APIGatewayProxyRequestEvent, Product>, Resource{
@Autowired
private DynamoProductDaoproductDao;
public GetProductByIdWithDynamoDBRequestPrimingHandler() {
Core.getGlobalContext().register(this);
}
...
public Productapply(APIGatewayProxyRequestEventrequestEvent) {
String id = requestEvent.getPathParameters().get("id");
return productDao.getProduct(id);
}
How to develop, run and optimize Spring Boot 3 application on AWS Lambda91
Spring Cloud Function for AWS (Priming of DynamoDB request)

Vadym Kazulkin| @VKazulkin |ip.labsGmbH
@Override
public void beforeCheckpoint(Context<? extends Resource> context) throws Exception {
productDao.getProduct("0");
}
@Override
public void afterRestore(Context<? extends Resource> context) throws Exception { }
}
How to develop, run and optimize Spring Boot 3 application on AWS Lambda92
Spring Cloud Function for AWS (Priming of DynamoDB request)

Vadym Kazulkin| @VKazulkin |ip.labsGmbH
AWS Lambda SnapStartwith Priming
Approach 2 Priming/Proxying the whole web
(API Gateway) request without going via
network
How to develop, run and optimize Spring Boot 3 application on AWS Lambda93

Vadym Kazulkin| @VKazulkin |ip.labsGmbH
public class StreamLambdaHandlerimplements RequestStreamHandler, Resource{
SpringBootLambdaContainerHandler<AwsProxyRequest, AwsProxyResponse> handler =
SpringBootLambdaContainerHandler.getAwsProxyHandler(Application.class);
@Autowired
private DynamoProductDaoproductDao;
public StreamLambdaHandler() {
Core.getGlobalContext().register(this);
}
@Override
public void handleRequest(InputStreaminputStream, OutputStreamoutputStream, Context context) {
handler.proxyStream(inputStream, outputStream, context);
}
How to develop, run and optimize Spring Boot 3 application on AWS Lambda94
AWS Serverless Java Container (Priming of API Gateway request)

Vadym Kazulkin| @VKazulkin |ip.labsGmbH
@Override
public void beforeCheckpoint(Context<? extends Resource> context) throws Exception {
handler.proxy(getAwsProxyRequest(), new MockLambdaContext());
}
@Override
public void afterRestore(Context<? extends Resource> context) throws Exception { }
How to develop, run and optimize Spring Boot 3 application on AWS Lambda95
AWS Serverless Java Container (Priming of API Gateway request)

Vadym Kazulkin| @VKazulkin |ip.labsGmbH
private static AwsProxyRequestgetAwsProxyRequest() {
final AwsProxyRequestawsProxyRequest= new AwsProxyRequest();
awsProxyRequest.setHttpMethod("GET");
awsProxyRequest.setPath("/products/0");
awsProxyRequest.setResource("/products/{id}");
awsProxyRequest.setPathParameters(Map.of("id","0"));
final AwsProxyRequestContextawsProxyRequestContext= new AwsProxyRequestContext();
final ApiGatewayRequestIdentityapiGatewayRequestIdentity= new ApiGatewayRequestIdentity();
apiGatewayRequestIdentity.setApiKey("blabla");
awsProxyRequestContext.setIdentity(apiGatewayRequestIdentity);
awsProxyRequest.setRequestContext(awsProxyRequestContext);
return awsProxyRequest;
}
}
How to develop, run and optimize Spring Boot 3 application on AWS Lambda96
AWS Serverless Java Container (Priming of API Gateway request)
Simulate
ApiGatewayProxyRequest

Vadym Kazulkin| @VKazulkin |ip.labsGmbH
This type of priming doesn’t work for AWS Web Adapter
as doesn’t offer low-level API to stream/proxy the API
Gatewayweb request
How to develop, run and optimize Spring Boot 3 application on AWS Lambda97

Vadym Kazulkin| @VKazulkin |ip.labsGmbH
@Component
public class GetProductByIdHandlerimplements
Function<APIGatewayProxyRequestEvent, Product>, Resource{
@Autowired
private DynamoProductDaoproductDao;
public GetProductByIdWithDynamoDBRequestPrimingHandler() {
Core.getGlobalContext().register(this);
}
...
public Productapply(APIGatewayProxyRequestEventrequestEvent) {
String id = requestEvent.getPathParameters().get("id");
returnproductDao.getProduct(id);
}
How to develop, run and optimize Spring Boot 3 application on AWS Lambda98
Spring Cloud Function for AWS (Priming of API Gateway request)

Vadym Kazulkin| @VKazulkin |ip.labsGmbH
@Override
public void beforeCheckpoint(Context<? extends Resource> context) throws Exception {
new FunctionInvoker().handleRequest(new
ByteArrayInputStream(getAPIGatewayRequestMultiLine().getBytes(StandardCharsets.UTF_8)),
new ByteArrayOutputStream(), new MockLambdaContext());}
@Override
public void afterRestore(Context<? extends Resource> context) throws Exception { }
}
How to develop, run and optimize Spring Boot 3 application on AWS Lambda99
Spring Cloud Function for AWS (Priming of API Gateway request)

Vadym Kazulkin| @VKazulkin |ip.labsGmbH
private static String getAPIGatewayRequestMultiLine() {
return “”” {
"resource": "/products/{id}",
"path": "/products/0",
"httpMethod": "GET",
"pathParameters": {
"id": "0"
},
"requestContext": {
"identity": {
"apiKey": "blabla"
} } }
“””;
} }
How to develop, run and optimize Spring Boot 3 application on AWS Lambda100
Spring Cloud Function for AWS (Priming of API Gateway request)
Simulate
ApiGatewayProxyRequest

Vadym Kazulkin| @VKazulkin |ip.labsGmbH
Lambda SnapStart Priming Guide
How to develop, run and optimize Spring Boot 3 application on AWS Lambda101
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
1000
2000
3000
4000
5000
6000
7000
AWS Serverless Java Container AWS Lambda Web Adapter Spring Cloud Function for AWS
w/o SnapStart w SnapStart no Priming
w SnapStart & DynamoDB request priming w SnapStart and API Gateway request priming
p90
ms

Vadym Kazulkin| @VKazulkin |ip.labsGmbH
0
1000
2000
3000
4000
5000
6000
7000
AWS Serverless Java
Container
AWS Lambda Web AdapterSpring Cloud Function for
AWS
Pure Java w/o framework
usage
w/o SnapStart w SnapStart no Priming
w SnapStart & DynamoDB request priming w SnapStart and API Gateway request priming
p90
ms

Vadym Kazulkin| @VKazulkin |ip.labsGmbH
0
500
1000
1500
2000
2500
AWS Serverless Java Container AWS Lambda Web Adapter Spring Cloud Function for AWS
w/o SnapStart w SnapStart no Priming
w SnapStart & DynamoDB request priming w SnapStart and API Gateway request priming
max value
ms

Vadym Kazulkin| @VKazulkin |ip.labsGmbH
0
500
1000
1500
2000
2500
AWS Serverless Java
Container
AWS Lambda Web AdapterSpring Cloud Function for
AWS
Pure Java w/o framework
usage
w/o SnapStart w SnapStart no Priming
w SnapStart & DynamoDB request priming w SnapStart and API Gateway request priming
max value
ms

Vadym Kazulkin| @VKazulkin |ip.labsGmbH
Other optimizations
High performance Serverless Java on AWS108
•Measure the cold and warm start of Lambda
with SnapStart enabled (and with priming) for
arm64 architecture and compare it to x86
•Measure the impact of the different Java
compilation options and memory settings
•Measure the impact of setting the different
synchronous HTTP clients
DynamoDbClientclient = DynamoDbClient.builder().region(Region.EU_CENTRAL_1)
. httpClient(ApacheHttpClient.create())
//.httpClient(UrlConnectionHttpClient.create())
//.httpClient(AwsCrtHttpClient.create())
.build();

Vadym Kazulkin| @VKazulkin |ip.labsGmbH
„AWS Lambda SnapStart „ series
How to develop, run and optimize Spring Boot 3 application on AWS Lambda109
https://dev.to/vkazulkin/measuring-java-11-lambda-cold-starts-with-snapstart-part-1-first-impressions-30a4
Article series covers they why and what
behind Lambda SnapStartand priming
techniques including measurements for cold
and warm starts with different settings for
▪Java 11
▪Java 17
▪Java 21
▪Micronaut
▪Quarkus
▪Spring Boot 2.7

Vadym Kazulkin| @VKazulkin |ip.labsGmbH
Lambda x86_64 vs arm64 architecture
High performance Serverless Java on AWS110
https://aws.amazon.com/de/about-aws/whats-new/2024/07/aws-lambda-snapstart-java-functions-arm64-architecture/

Vadym Kazulkin| @VKazulkin |ip.labsGmbH
Lambda x86_64 vs arm64 architecture
High performance Serverless Java on AWS111
https://aws.amazon.com/lambda/pricing/?nc1=h_ls
For the same memory setting Lambda and
Lambda function execution duration the choice of
arm64 over x86_64 architecture is approx. 25%
cheaper

Vadym Kazulkin| @VKazulkin |ip.labsGmbH
0
500
1000
1500
2000
2500
3000
3500
4000
4500
w/o AWS SnapStart with AWS SnapStart w/o priming with AWS SnapStart with priming
Cold starts of the pure Lambda function (no framework in use)
with Java 21runtime with
1024 MB memory setting, Apache Http Client, compilation
-XX:+TieredCompilation -XX:TieredStopAtLevel=1 for p90
x86_64arm64
ms
https://dev.to/aws-builders/aws-snapstart-part-16-measuring-cold-and-warm-starts-with-java-21-using-different-asynchronous-http-clients-4n2
+8,6%
+23,9%
+24,8%

Vadym Kazulkin| @VKazulkin |ip.labsGmbH
6,40
6,60
6,80
7,00
7,20
7,40
7,60
7,80
8,00
w/o AWS SnapStart with AWS SnapStart w/o priming with AWS SnapStart with priming
Warm starts of pure Lambda function (no framework in use)
with Java 21runtime with
1024 MB memory setting, Apache Http Client, compilation
-XX:+TieredCompilation -XX:TieredStopAtLevel=1 for p90
x86_64arm64
ms
https://dev.to/aws-builders/aws-snapstart-part-16-measuring-cold-and-warm-starts-with-java-21-using-different-asynchronous-http-clients-4n2
+9,1%
+10,1%
+4,8%

Vadym Kazulkin| @VKazulkin |ip.labsGmbH
AWS SnapStartDeployment & Invocation
How to develop, run and optimize Spring Boot 3 application on AWS Lambda114
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/
Firecracker microVM
create & restore
snapshot

Vadym Kazulkin| @VKazulkin |ip.labsGmbH
Demo Application
How to develop, run and optimize Spring Boot 3 application on AWS Lambda115
https://github.com/Vadym79/AWSLambdaJavaWithSpringBoot
▪Used Spring 3.2 with Amazon Corretto
Java 21
▪Lambda has 1024 MB memory setting
▪Lambda uses x86 architecture
▪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 SnapStarttiered cache
How to develop, run and optimize Spring Boot 3 application on AWS Lambda116
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
How to develop, run and optimize Spring Boot 3 application on AWS Lambda117
https://www.infoq.com/articles/aws-lambda-under-the-hood/
https://www.infoq.com/presentations/aws-lambda-arch/

Vadym Kazulkin| @VKazulkin |ip.labsGmbH
▪SnapStartsupports the Java 11, 17 and 21 (Corretto) 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
▪arm64 architecture (supports only x86). Supports arm64 architecture since
18 July 2024
▪Amazon Elastic File System (Amazon EFS)
▪Ephemeral storage greater than 512 MB
AWS SnapStart Challenges & Limitations
How to develop, run and optimize Spring Boot 3 application on AWS Lambda118
https://docs.aws.amazon.com/lambda/latest/dg/snapstart.html

Vadym Kazulkin| @VKazulkin |ip.labsGmbH
▪AWS Serverless Java Container and AWS Lambda Web Adapter offer similar
functionality
▪AWS Serverless Java Container offers a bit lower warm start times
▪AWS Serverless Java Container offers more flexibility to apply priming techniques to the
individual Lambda functions in the deployment artifact through its API
▪AWS Lambda Web Adapter offers lower cold start times (with SnapStartand priming)
▪AWS Lambda Web Adapter offers more event triggers (non HTTP events)
▪Spring Cloud Function makes sense if already in use
▪AWS Serverless Java Container (since 2.0.2) and Spring Cloud Function both
support GraalVMNative Image
▪Using Docker Image leads to the highest cold start.
▪You can use the recent Java version though and use jlinkto reduce the size of the JDK
Framework Comparison
How to develop, run and optimize Spring Boot 3 application on AWS Lambda120
https://www.azul.com/blog/superfast-application-startup-java-on-crac/ https://github.com/CRaC/docs

Vadym Kazulkin| @VKazulkin |ip.labsGmbH121 How to develop, run and optimize Spring Boot 3 application on AWS Lambda

Vadym Kazulkin| @VKazulkin |ip.labsGmbH
▪Low footprint ahead-of-time mode for JVM-based languages
▪High performance for all languages
▪Convenient language interoperability and polyglot tooling
GraalVMGoals
How to develop, run and optimize Spring Boot 3 application on AWS Lambda122
Source: „Everything you need to know about GraalVMby Oleg Šelajev& Thomas Wuerthinger” https://www.youtube.com/watch?v=ANN9rxYo5Hg

Vadym Kazulkin| @VKazulkin |ip.labsGmbH
GraalVMArchitecture
How to develop, run and optimize Spring Boot 3 application on AWS Lambda123

Vadym Kazulkin| @VKazulkin |ip.labsGmbH
GraalVMAhead-of-Time Compilation
How to develop, run and optimize Spring Boot 3 application on AWS Lambda124
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
How to develop, run and optimize Spring Boot 3 application on AWS Lambda125
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 executableusing GraalVMNative
Imagesignificantly reduces
▪“cold start” times
▪memory footprint
GraalVMNative Image
How to develop, run and optimize Spring Boot 3 application on AWS Lambda126

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
How to develop, run and optimize Spring Boot 3 application on AWS Lambda127

Vadym Kazulkin| @VKazulkin |ip.labsGmbH
Custom Lambda Runtimes
How to develop, run and optimize Spring Boot 3 application on AWS Lambda128
https://github.com/Vadym79/AWSLambdaGraalVMNativeImage

Vadym Kazulkin| @VKazulkin |ip.labsGmbH
GraalVMRelease Calendar
How to develop, run and optimize Spring Boot 3 application on AWS Lambda129
https://www.graalvm.org/release-calendar/

Vadym Kazulkin| @VKazulkin |ip.labsGmbH
GraalVMCE is based on OpenJDK
How to develop, run and optimize Spring Boot 3 application on AWS Lambda130
https://www.graalvm.org/2022/openjdk-announcement/
https://blogs.oracle.com/java/post/graalvm-free-license

Vadym Kazulkin| @VKazulkin |ip.labsGmbH
▪Spring Boot 3+ provides official support for
compiling Spring Boot applications into the GraalVM
Native Image
▪Spring AOT (Ahead-of-Time Processing) is a process
that analyzes your application at build-time and
generate an optimized version of it. It is a mandatory
step to run a Spring ApplicationContextin a native
image
Spring Supprtfor GraalVMNative Image
How to develop, run and optimize Spring Boot 3 application on AWS Lambda131
https://docs.spring.io/spring-boot/maven-plugin/aot.html

Vadym Kazulkin| @VKazulkin |ip.labsGmbH
pom.xml
<profiles>
<profile>
<id>native</id>
<activation>
<property>
<name>native</name>
</property>
</activation>
....
</profile>
</profiles>
GraalVMNative Image with Spring Cloud Function
How to develop, run and optimize Spring Boot 3 application on AWS Lambda132
mvn clean package -Pnative
https://github.com/Vadym79/AWSLambdaJavaWithSpringBoot/tree/master/spring-boot-3.2-with-graalvm-native-image

Vadym Kazulkin| @VKazulkin |ip.labsGmbH
pom.xml
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<id>process-aot</id>
<goals>
<goal>process-aot</goal>
</goals>
</execution>
</executions>
</plugin>
GraalVMNative Image with Spring Cloud Function
How to develop, run and optimize Spring Boot 3 application on AWS Lambda133
https://github.com/Vadym79/AWSLambdaJavaWithSpringBoot/tree/master/spring-boot-3.2-with-graalvm-native-image

Vadym Kazulkin| @VKazulkin |ip.labsGmbH
pom.xml
<plugin>
<groupId>org.graalvm.buildtools</groupId>
<artifactId>native-maven-plugin</artifactId>
<configuration>
<mainClass>software.amazonaws.Application</mainClass>
</configuration>
<executions>
<execution>
<id>build-native</id>
<goals>
<goal>compile-no-fork</goal>
</goals>
GraalVMNative Image with Spring Cloud Function
How to develop, run and optimize Spring Boot 3 application on AWS Lambda134
https://github.com/Vadym79/AWSLambdaJavaWithSpringBoot/tree/master/spring-boot-3.2-with-graalvm-native-image
<phase>package</phase>
</execution>
</executions>
</plugin>

Vadym Kazulkin| @VKazulkin |ip.labsGmbH
▪You can run into errors when
application is running
GraalVM Native Image
High performance Serverless Java on AWS135
https://github.com/Vadym79/AWSLambdaGraalVMNativeImage/blob/master/pure-lambda-graalvm-jdk-21-native-image/src/main/reflect.json

Vadym Kazulkin| @VKazulkin |ip.labsGmbH
import org.springframework.aot.hint.RuntimeHints;
import org.springframework.aot.hint.RuntimeHintsRegistrar;
import
org.springframework.aot.hint.annotation.RegisterReflection
ForBinding;
@Configuration
@RegisterReflectionForBinding({DateTime.class,
APIGatewayProxyRequestEvent.class, HashSet.class,
APIGatewayProxyRequestEvent.ProxyRequestContext.class,
APIGatewayProxyRequestEvent.RequestIdentity.class,
Product.class, Products.class})
@ImportRuntimeHints(ApplicationConfiguration.Application
RuntimeHintsRegistrar.class)
GraalVMNative Image with Spring Cloud Function
How to develop, run and optimize Spring Boot 3 application on AWS Lambda136
public class ApplicationConfiguration {

public static class ApplicationRuntimeHintsRegistrar
implements RuntimeHintsRegistrar {
@Override
public void registerHints(RuntimeHints hints,
ClassLoader classLoader) {
hints.reflection() .registerType(Product.class,
PUBLIC_FIELDS, INVOKE_PUBLIC_METHODS,
INVOKE_PUBLIC_CONSTRUCTORS
;
}
}
}
https://github.com/Vadym79/AWSLambdaJavaWithSpringBoot/tree/master/spring-boot-3.2-with-graalvm-native-image

Vadym Kazulkin| @VKazulkin |ip.labsGmbH
950
1000
1050
1100
1150
1200
1250
GraalVM 21 Native Image with Spring Cloud Function for AWS
p50p75p90p99p99.9max
1024 MB
memory
ms

Vadym Kazulkin| @VKazulkin |ip.labsGmbH
0
50
100
150
200
250
GraalVM 21 Native Image with Spring Cloud Function for AWS
p50p75p90p99p99.9max
1024 MB
memory
ms

Vadym Kazulkin| @VKazulkin |ip.labsGmbH
0
1000
2000
3000
4000
5000
6000
7000
AWS Serverless Java
Container
AWS Lambda Web AdapterSpring Cloud Function for
AWS
Graal VM 21 Native Image
with Spring Cloud Function
for AWS
w/o SnapStart w SnapStart no Priming
w SnapStart & DynamoDB primingw SnapStart and Web priming
p90

Vadym Kazulkin| @VKazulkin |ip.labsGmbH
0
500
1000
1500
2000
2500
AWS Serverless Java
Container
AWS Lambda Web AdapterSpring Cloud Function for
AWS
Graal VM 21 Native Image
with Spring Cloud Function
for AWS
w/o SnapStart w SnapStart no Priming
w SnapStart & DynamoDB primingw SnapStart and Web priming
max value
ms

Vadym Kazulkin| @VKazulkin |ip.labsGmbH
0
200
400
600
800
1000
1200
1400
GraalVM 21 Native Image with Spring Cloud Function
for AWS
GraalVM 21 Native Image with Pure Java w/o
framework usage
p50p75p90p99p99.9max
1024 MB
memory
https://github.com/Vadym79/AWSLambdaJavaWithSpringBoot/tree/master/spring-boot-3.2-with-graalvm-native-image
https://github.com/Vadym79/AWSLambdaGraalVMNativeImage/tree/master/pure-lambda-graalvm-jdk-21-native-image
ms

Vadym Kazulkin| @VKazulkin |ip.labsGmbH
GraalVM 21 Native Image for Spring Cloud Function for
AWS
How to develop, run and optimize Spring Boot 3 application on AWS Lambda142
ONE SECOND ONE GB

Vadym Kazulkin| @VKazulkin |ip.labsGmbH
0
200
400
600
800
1000
1200
1400
1600
1800
2000
256 MB 512 MB 768 MB 1024 MB 1280 MB 1536 MB
p50p75p90p99p99.9max
GraalVM 21
Native Image
with Spring
Cloud
Function for
AWS
ms

Vadym Kazulkin| @VKazulkin |ip.labsGmbH
0
100
200
300
400
500
600
700
800
900
1000
256 MB 512 MB 768 MB 1024 MB 1280 MB 1536 MB
p50p75p90p99p99.9max
GraalVM 21
Native Image
with Spring
Cloud
Function for
AWS
ms

Vadym Kazulkin| @VKazulkin |ip.labsGmbH
▪GraalVMis really powerful and has a lot of potential
▪GraalVMNative Image improves cold starts and memory footprint significantly
▪GraalVMNative Image is currently not without challenges
▪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
▪You pay for the init-phase of the function packaged as AWS Lambda Custom
and Docker Runtime
▪Init-phase is free for the managed runtimes like Java 11, Java17 and Java 21
GraalVM Conclusion
How to develop, run and optimize Spring Boot 3 application on AWS Lambda145

Vadym Kazulkin| @VKazulkin |ip.labsGmbH
Frameworks and libraries Ready for GraalVMNative Image
How to develop, run and optimize Spring Boot 3 application on AWS Lambda146
https://www.graalvm.org/native-image/libraries-and-frameworks/

Vadym Kazulkin| @VKazulkin |ip.labsGmbH
“Spring Boot 3 application on AWS Lambda” series
How to develop, run and optimize Spring Boot 3 application on AWS Lambda147
Article series covers different
ways to write Spring Boot 3
application on AWS Lambda
▪AWS Serverless Java Container
▪AWS Lambda Web Adapter
▪Spring Cloud Functions
▪Custom Docker Image
▪GraalVMNative Image
Cold and warm start time
measurements are also provided
https://dev.to/aws-builders/spring-boot-3-application-on-aws-lambda-part-1-introduction-to-the-series-2m5g

Vadym Kazulkin| @VKazulkin |ip.labsGmbH
“Data API for Amazon Aurora Serverless v2
with AWS SDK for Java” series
How to develop, run and optimize Spring Boot 3 application on AWS Lambda148
Article series also covers
cold and warm start time
measurements and
optimization techniques
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

Vadym Kazulkin| @VKazulkin |ip.labsGmbH
Word of caution
How to develop, run and optimize Spring Boot 3 application on AWS Lambda149
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
▪Spring Boot 3 version updates (already 3.3.
released, tested with 3.2.)
▪Lambda SnapStartsnapshot create and
restore improvements
▪Firecracker VM improvements
▪GraalVMand Native Image improvements
(already version 22 released, tested with 21)
▪There are still servers behind Lambda
▪Java Memory Model impact (L or RAM
caches hits and misses)

Vadym Kazulkin| @VKazulkin |ip.labsGmbH
▪Spring Boot natively supports CRaC
▪For Checkpoint: -Dspring.context.checkpoint=onRefresh-XX:CRaCCheckpointTo={path}
▪For Restore: -XX:CRaCRestoreFrom={path}
▪Amazon Correttodoesn’t support CRaC
▪Azul Zulu OpenJDK supports CRaC
▪Can be deployed on Lambda with Docker Container Image
▪Currently very complicated and partially possible with hacks and many trade-offs
▪Mounting EFS for CRaCsnapshot. Requires Lambda being in VPC and managing EFS
throughput
Spring Boot Native CRaC Support
How to develop, run and optimize Spring Boot 3 application on AWS Lambda150
https://github.com/CRaC/example-lambda/issues/7

Vadym Kazulkin| @VKazulkin |ip.labsGmbH
▪With AWS SnapStartand GraalVMNative Image you can reduce cold
start timesof the Spring Boot 3 application on AWS Lambda 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
crucial for your business -> go for GraalVMNative Image
Wrap up and personal suggestions
How to develop, run and optimize Spring Boot 3 application on AWS Lambda151

Vadym Kazulkin| @VKazulkin |ip.labsGmbH
Project Leyden
High performance Serverless Java on AWS152
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
FAQ Ask me Anything
How to develop, run and optimize Spring Boot 3 application on AWS Lambda153

Vadym Kazulkin| @VKazulkin |ip.labsGmbH154 How to develop, run and optimize Spring Boot 3 application on AWS Lambda
Thank you