GraalVM + AWS Lambda or solving Java cold start problem

Our test architecture

API-Gateway -> AWS Lambda->DynamoDb

Version 1 (plain Java without improvements)

  • Java 11
  • AWS SDK-V2 for DynamoDB(extended DynamoDb client)
  • No DI (Spring, Dagger, etc)
  • No special frameworks


Cold start for version 1 (256 Mb)

Version 2(plain Java with improvements)

  • Java 11
  • AWS SDK-V2 for Dynamodb
  • No DI (Spring, etc)
  • No special frameworks
  • Utilize CPU burst on startup (move everything to static, warm-up dynamoDB client)
  • Reduce dependencies(exclude Netty)
  • Specify AWS Regions
  • Specify Credential Provider


X-Ray trace for the first call

What is AWS Lambda Custom runtime?

  • Just a with a bootstrap shell script or binary executable file (compiled for Amazon Linux)
  • Any programming language
  • Not a new feature (since 2018)


GraalVM JIT and AOT

AOT vs JIT: Startup Time


  • Load JVM executables
  • Load classes from the file system
  • Verify bytecodes
  • Start interpreting
  • Run static initializers
  • First-tier compilation
  • Gather profiling feedback
  • Second tire compilation(C2 or GraalVM)
  • Finally, run with the best machine code
  • Load executable with a prepared heap
  • Immediately start with the best machine code

Version 3 (AWS Lambda Custom Runtime + GraalVM)

Code is here


GraalVM X-Ray tracing for 256MB
  • Only Serial GC is supported for GraalVM CE version(Enterprise has G1)
  • Use Quarkus, Micronaut, etc


Cold start comparison
Orange is GraalVM, red is Java



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