Micronaut JPA Function Performance on AWS Lambda

In this article, I would be talking about the performance statistics when running a Micronaut Application on a JVM runtime versus running it as a native image on the Lambda.


Micronaut became quite popular for their quick startup time because of the Ahead Of Time(AOT) compilation. It provides literally all the capabilities that SpringBoot provides like Aspect-Oriented programming, Dependency injection, etc.

Now I have described how to create a Micronaut Application in my previous article “A SpringBoot Developer’s Guide to Micronaut”. I have also described how you can boost your application performance in another article “Boot Java Application Performance with Micronaut Native Image”.

Today, we would be looking at creating an AWS Lamda function with Micronaut and seeing its performance statistics when we deploy it on JVM runtime and as a Native Image on Amazon Linux custom runtime image.

So let’s get started.

Micronaut Function On AWS Lambda

In this, we would be creating a Micronaut function that takes an Order, persists on AWS RDS, and then returns the created ID.

You can generate an application from Micronaut’s launch. Here you select the application type as “Function Application For Serverless” and in the features, add “Hibernate-JPA” and “AWS-Lambda”.

Once you open the generated project, We will create our function handler by extending Micronaut’s Request handler MicronautRequestHandler and override the execute method.

public class OrderRequestHandler extends MicronautRequestHandler<Order, Order> {

private OrderRepository orderRepository;

public Order execute(Order input) {
Order saved = this.orderRepository.save(input);
return saved;

The repository is a simple JPA repository as follows.

public interface OrderRepository extends JpaRepository<Order, Long>{ }

In the application.yml file, add data source properties to communicate with the AWS RDS instance.

url: jdbc:mysql://database.whgnes.eu-central1.rds.amazonaws.com:3306/ORDERS_DB?characterEncoding=UTF-8
username: admin
password: nopass
driverClassName: com.mysql.cj.jdbc.Driver
auto: update
show_sql: true
dialect: org.hibernate.dialect.MySQL8Dialect

With this, we can start creating a jar using mvn clean package.

Next, we will create an AWS Lambda function with the runtime as Java 11, upload the jar, and set the handler function to com.amrut.prabhu.OrderRequestHandler.

Let’s test this with the following payload.

"body": "{\"name\":\"Order from Lambda\"}"

Here are the statistics I got with the Lamba configured with 512 MB ram.

Now, this was what we got from the Lambda using the JVM runtime. Let’s look at improving this by creating a native image.

AWS Lambda with Native Image Using GraalVM

To support creating the native image, we would have to do some changes to the code above.

Firstly, you will need to add a dependency to support creating the native image for the AWS lambda function


Next, You will need to create a custom initializer by extending AbstractMicronautLambdaRuntime .

public class OrderLambdaRuntime extends AbstractMicronautLambdaRuntime<APIGatewayProxyRequestEvent, APIGatewayProxyResponseEvent, Order, Order> {public static void main(String[] args) {
try {
new OrderLambdaRuntime().run(args);
} catch (MalformedURLException e) {

protected RequestHandler<Order, Order> createRequestHandler(String... args) {
return new OrderRequestHandler();

In addition to this, You will need to set the main class in the properties section of your pom.


With this, you are done with your code changes.

Next, To create the naive image, You need to set your default JDK to GraalVM JDK. I have used GraalVM CE 21.1.0 (build 11.0.11). You can easily install this using SDKMan.

Now let’s build the native image using the following command. Make sure you also have docker installed, as it makes use of the docker to download the AWS runtime image to build the native image.

./mvnw clean package -Dpackaging=docker-native -Dmicronaut.runtime=lambda

Creating the native image might take some time, Maybe around 3–5mins depending on the system. The output is a zip file that contains the required bootstrap files to start the application.

Once created, Let’s upload the zip and set the runtime to the custom runtime option “Provide your own bootstrap on Amazon Linux 2”. In the case of the handler function, It doesn’t matter if you do not set it, as the Lambda would use your native image bootstrap file to start the application.

Now, On invoking the function with the same payload as above, we get a huge change in the performance.

The init duration is now reduced to 761 ms. The execution time during the cold start remains the same i.e 1215 ms. But for subsequent calls, The response time is less than half of the previous results ie. 14 ms.

Here are the statistics to compare between using a JVM runtime and the native image.

So as you can see, we can achieve really high performance by building and using a native image.

You can have a look at the code on my GitHub repo.

More to come...

In this article, we used a single function to add an object to the RDS database. But what about cases wherein you would want to add as well as retrieve an object. For this, We will be looking into deploying a Micronaut application on AWS Lambda providing PUT and GET capabilities and see its performance.

You can subscribe to my newsletter on RefactorFirst.com to get an email when I publish my articles.




Software Craftsman, Tech Enthusiast. I run https://refactorfirst.com to post all my articles

Love podcasts or audiobooks? Learn on the go with our new app.

Recommended from Medium

How to Create a Simple Login and Registration App in Android Studio That Displays Username Using…

Web Development with Flask

SOLID Programming in 10 minutes

Building a PM 2.5 dust sensor with Arduino

Building a secure FHIR Server. Why and How?

How to Sabotage A Scrum Master

GCP IIoT: Visualization and Analytics in Looker for Oil & Gas Systems

How to get the MX6 SSI port up and running in TDM mode

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Amrut Prabhu

Amrut Prabhu

Software Craftsman, Tech Enthusiast. I run https://refactorfirst.com to post all my articles

More from Medium

How to Use AWS Parameter Store

Deploy your Java Lambda easily with Microlam!

Tracing Java based Lambda using X-Ray and AWS PowerTools

Example of Spring Cloud Function with AWS Lambda