Is Java on AWS Lambda slow?

Java running on AWS Lambda is slow the first time, but I searched for a way to make it faster. I arrived at the contents of the reference site at the end and actually tried it, so it is a record.

Latency information was obtained by X-Ray.

Test target

Just put the file to S3

S3Client s3 = S3Client.builder().region(Region.AP_NORTHEAST_1).build();
PutObjectResponse result = s3.putObject(
        PutObjectRequest.builder().bucket(ENV_BUCKET).key("filename.txt").build(),
        RequestBody.fromString("contents"));

Verification 1 Normal execution

First, try it normally.

entire source
package helloworld;

import com.amazonaws.services.lambda.runtime.Context;
import com.amazonaws.services.lambda.runtime.RequestHandler;

import software.amazon.awssdk.core.sync.RequestBody;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.s3.S3Client;
import software.amazon.awssdk.services.s3.model.PutObjectRequest;
import software.amazon.awssdk.services.s3.model.PutObjectResponse;

public class TestTarget0429 implements RequestHandler<Object, Object> {

    public Object handleRequest(final Object input, final Context context) {
        String ENV_BUCKET = System.getenv("BUCKET");

        S3Client s3 = S3Client.builder().region(Region.AP_NORTHEAST_1).build();
        PutObjectResponse result = s3.putObject(
                PutObjectRequest.builder().bucket(ENV_BUCKET).key("filename.txt").build(),
                RequestBody.fromString("contents"));

        System.out.println(result);

        return null;
    }
}
Number of times Latency(ms) Processing content
1 6200
2 422
3 217
4 210
5 315

Only the first time is late, so-called cold start is late. Just creating one file in S3 is 6 seconds slow, isn't it?

Verification 2 Enable Provisioned Concurrency

So how about using the Provisioned Concurrency that appeared at the end of last year? https://aws.amazon.com/jp/blogs/news/new-provisioned-concurrency-for-lambda-functions/

The source code is the same as Verification 1.

Number of times Latency(ms) Processing content
1 5500
2 266
3 274
4 402
5 304

** Isn't the first time still late? .. ** ** It costs $ 14.42 a month just to provision Concurrency 1, but that's not enough. .. ..

So, after that, disable Provisioned Concurrency and continue verification

Verification 3 Separation of processing (without Provisioned Concurrency)

In order to find out the cause of the slowness at the first time, I tried to separate the processing at the first startup of Lambda and the second startup.

Create a static count variable and try a haste return only the first call.

        if (count == 1) {
            count++;
            return null;
        }
entire source
package helloworld;

import com.amazonaws.services.lambda.runtime.Context;
import com.amazonaws.services.lambda.runtime.RequestHandler;

import software.amazon.awssdk.core.sync.RequestBody;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.s3.S3Client;
import software.amazon.awssdk.services.s3.model.PutObjectRequest;
import software.amazon.awssdk.services.s3.model.PutObjectResponse;

public class TestTarget0429 implements RequestHandler<Object, Object> {

    private static int count = 1;

    public Object handleRequest(final Object input, final Context context) {
        if (count == 1) {
            count++;
            return null;
        }
        
        String ENV_BUCKET = System.getenv("BUCKET");

        S3Client s3 = S3Client.builder().region(Region.AP_NORTHEAST_1).build();
        PutObjectResponse result = s3.putObject(
                PutObjectRequest.builder().bucket(ENV_BUCKET).key("filename.txt").build(),
                RequestBody.fromString("contents"));

        System.out.println(result);

        return null;
    }
}

result

Number of times Latency Processing content
1 625ms Initialization process only
2 5600ms S3 PUT (1st time)
3 393ms S3 PUT (2nd time)
4 401ms S3 PUT (3rd time)
5 311ms S3 PUT (4th time)

It turns out that the Initialization process is not slow. It seems that S3 PUT (first time) is taking a long time.

Verification 4 Make the initialization process static (no Provisioned Concurrency)

Let's make the part that creates S3Client static.

private static String ENV_BUCKET = System.getenv("BUCKET");
private static S3Client s3 = S3Client.builder().region(Region.AP_NORTHEAST_1).build();
entire source
package helloworld;

import com.amazonaws.services.lambda.runtime.Context;
import com.amazonaws.services.lambda.runtime.RequestHandler;

import software.amazon.awssdk.core.sync.RequestBody;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.s3.S3Client;
import software.amazon.awssdk.services.s3.model.PutObjectRequest;
import software.amazon.awssdk.services.s3.model.PutObjectResponse;

public class TestTarget0429 implements RequestHandler<Object, Object> {

    private static int count = 1;

    private static String ENV_BUCKET = System.getenv("BUCKET");
    private static S3Client s3 = S3Client.builder().region(Region.AP_NORTHEAST_1).build();

    public Object handleRequest(final Object input, final Context context) {
        if (count == 1) {
            count++;
            return null;
        }

        PutObjectResponse result = s3.putObject(
                PutObjectRequest.builder().bucket(ENV_BUCKET).key("filename.txt").build(),
                RequestBody.fromString("contents"));

        System.out.println(result);

        return null;
    }
}

result

Number of times Latency Processing content
1 2400ms Initialization process and S3Client instance generation
2 2200ms S3 PUT (1st time)
3 43ms S3 PUT (2nd time)
4 46ms S3 PUT (3rd time)
5 78ms S3 PUT (4th time)

Oh! It took a little longer to process the first time, and the second time was a little faster. It's getting faster after the third time, but is this also having any effect?

Verification 5 Do it once with static initializer (without Provisioned Concurrency)

I found that processing with static makes it faster. Let's create a dummy file with the static initializer once.

static{
    PutObjectResponse result = s3.putObject(
            PutObjectRequest.builder().bucket(ENV_BUCKET).key("dummy.txt").build(),
            RequestBody.fromString("contents"));

    System.out.println(result);
}
entire source
package helloworld;

import com.amazonaws.services.lambda.runtime.Context;
import com.amazonaws.services.lambda.runtime.RequestHandler;

import software.amazon.awssdk.core.sync.RequestBody;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.s3.S3Client;
import software.amazon.awssdk.services.s3.model.PutObjectRequest;
import software.amazon.awssdk.services.s3.model.PutObjectResponse;

public class TestTarget0429 implements RequestHandler<Object, Object> {

    private static int count = 1;

    private static String ENV_BUCKET = System.getenv("BUCKET");
    private static S3Client s3 = S3Client.builder().region(Region.AP_NORTHEAST_1).build();

    static{
        PutObjectResponse result = s3.putObject(
                PutObjectRequest.builder().bucket(ENV_BUCKET).key("dummy.txt").build(),
                RequestBody.fromString("contents"));

        System.out.println(result);
    }

    public Object handleRequest(final Object input, final Context context) {
        if (count == 1) {
            count++;
            return null;
        }

        PutObjectResponse result = s3.putObject(
                PutObjectRequest.builder().bucket(ENV_BUCKET).key("filename.txt").build(),
                RequestBody.fromString("contents"));

        System.out.println(result);

        return null;
    }
}

result

Number of times Latency Processing content
1 4000ms S3 PUT (first time) dummy file by Initialization processing and static method
2 42ms S3 PUT (2nd time)
3 125ms S3 PUT (3rd time)
4 42ms S3 PUT (4th time)
5 44ms S3 PUT (5th time)

Congratulations, the second and subsequent times have become faster!

Verification 6 Verification 5 + Provisioned Concurrency

Since it became faster in verification 5, will it be faster from the first time if combined with Provisioned Concurrency? !!

The source is the same as Verification 5.

Number of times Latency Processing content
1 80ms Initialization process
2 370ms S3 PUT (2nd time) * Because it has been executed once with the static initializer at the time of Provisioned
3 43ms S3 PUT (3rd time)
4 72ms S3 PUT (4th time)
5 84ms S3 PUT (5th time)

** I did it! ** ** This is what I expected.

Final result

The final form is like this.

entire source
package helloworld;

import com.amazonaws.services.lambda.runtime.Context;
import com.amazonaws.services.lambda.runtime.RequestHandler;

import software.amazon.awssdk.core.sync.RequestBody;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.s3.S3Client;
import software.amazon.awssdk.services.s3.model.PutObjectRequest;
import software.amazon.awssdk.services.s3.model.PutObjectResponse;

public class TestTarget0429 implements RequestHandler<Object, Object> {

    private static String ENV_BUCKET = System.getenv("BUCKET");
    private static S3Client s3 = S3Client.builder().region(Region.AP_NORTHEAST_1).build();

    static{
        PutObjectResponse result = s3.putObject(
                PutObjectRequest.builder().bucket(ENV_BUCKET).key("dummy.txt").build(),
                RequestBody.fromString("contents"));

        System.out.println(result);
    }

    public Object handleRequest(final Object input, final Context context) {
        PutObjectResponse result = s3.putObject(
                PutObjectRequest.builder().bucket(ENV_BUCKET).key("filename.txt").build(),
                RequestBody.fromString("contents"));

        System.out.println(result);

        return null;
    }
}
Number of times Latency Processing content
1 552ms S3 PUT (2nd time) * Because it has been executed once with the static initializer at the time of Provisioned
2 118ms S3 PUT (3rd time)
3 44ms S3 PUT (4th time)
4 86ms S3 PUT (5th time)
5 146ms S3 PUT (6th time)

Congratulations, congratulations.

Consideration

Apparently, the Java class loader loads the class when the class is called for the first time, and it seems that the initial loading of the class takes time. So, it seems that if you load it once and load the class, it will be faster from the next time.

It would be nice if all the classes were loaded first, not when they were called, but isn't that possible?

The reference site is here.

Class method's blog https://dev.classmethod.jp/articles/report-best-practive-for-java-on-lambda/

Session materials at re: Invent 2019 https://d1.awsstatic.com/events/reinvent/2019/REPEAT_1_Best_practices_for_AWS_Lambda_and_Java_SVS403-R1.pdf https://youtu.be/ddg1u5HLwg8

Other blogs I found https://pattern-match.com/blog/2020/03/14/springboot2-and-aws-lambda-provisioned-concurrency/

Recommended Posts

Is Java on AWS Lambda slow?
Hello World on AWS Lambda + Java
Regularly post imaged tweets on Twitter with AWS Lambda + Java
What is a lambda expression (Java)
Run C binaries on AWS Lambda
AWS Lambda with Java starting now Part 1
Build Java 8 development environment on AWS Cloud9
What is java
What is Java <>?
What is Java
Hello Java Lambda
[Java] Lambda expression
Java lambda expression
How to deploy a container on AWS Lambda
Create a Lambda Container Image based on Java 15
How to use Java framework with AWS Lambda! ??
Let's touch on Java
Install Java on Mac
How to deploy Java to AWS Lambda with Serverless Framework
AWS Lambda timezone change
java neutral lambda expression 1
Lambda on Terraform Container
Quarkus saves Java Lambda! ??
Run PostgreSQL on Java
Understand Java 8 lambda expressions
Java lambda expression variations
What is Java Encapsulation?
You can do it right away with Serverless Framework Serverless on AWS (API + Lambda [java] is easy to set up)
Java 8 lambda expression Feature
java lambda expression memo
About Java lambda expressions
What is Java technology?
What is Java API-java
Java lambda expression [memo]
Explain Java 8 lambda expressions
Studying Java 8 (lambda expression)
Review java8 ~ Lambda expression ~
Java lambda expression again
[Java] What is flatMap?
[Java] What is JavaBeans?
[Java] What is ArrayList?
Java Lambda Command Pattern
Create a SlackBot with AWS lambda & API Gateway in Java
How to deploy a kotlin (java) app on AWS fargate
Tips around the sample to release Java Lambda on CodePipeline
[Java] Code that is hard to notice but terribly slow
Java version control on macOS
Use Lambda Layers with Java
What is Java Assertion? Summary.
Install OpenJDK7 (JAVA) on ubuntu 14.04
Downgrade Java on openSUSE Linux
On passing Java Gold SE 8
Oracle Java 8 on Docker Ubuntu
Java8 stream, lambda expression summary
With [AWS] CodeStar, you can build a Spring (Java) project running on Lambda in just 3 minutes! !!
[Java] Introduction to lambda expressions
Install Java on WSL Ubuntu 18.04
What is a Java collection?
[Windows] Java code is garbled
What is a lambda expression?
Run java applet on ubuntu