javaspring-bootaws-lambdawarm-upcold-start

AWS Lambda cold start issue with spring boot


I am new to aws lambda and I am moving my spring boot 2.x based project to lambda.But I am struggling with lambda cold-start and warm-up. I tried a few things mentioned in this link:https://github.com/awslabs/aws-serverless-java-container/wiki/Quick-start---Spring-Boot, but still the application takes around 45 secs to start.

Things I tried:

  1. Async initialization from the above link. It did help a bit but not enough.

  2. Skip the Init phase of the lambda. It helped reduce almost 8 secs.

  3. Provisioned concurrency but as far as I could see, it is not helping either. When I saw the logs, the spring context is getting initialized every time, if any request comes after an interval of 15-20 mins.

The response time of my lambda in different scenarios is:

1. 3008 MB memory/first request/ response time: ~25 secs.  
2. 3008 MB memory/2nd request immediately after 1st req/ response time: ~600ms.  
3. 1024 MB memory/1st req/ postman request times out.  
4. 1024 MB memory/2nd req immediately after 1st req/response time:  ~750ms.  
5. 1792 MB memory/1st req/ response time: ~27sec.  
6. 1792 MB memory/ 2nd req immediately after 1st req/response time:  ~650ms

To reduce this response time, I am thinking of making a REST call to my lambda every 5 or 10 mins so as to keep the spring context in memory and that in turn would help serve the requests faster. This call will be like a health check call, very less to no processing at all.

Is this an advisable approach? Or is there a better way of achieving this goal?

I am unclear about AWS will charge in this case.


Solution

  • A 5 minute Cloudwatch Event would come out to arount 8600 calls / month. If you ran even 100000 calls it's still free according to the calculator on https://aws.amazon.com/lambda/pricing/ with 3GB of memory.

    To configure Cloudwatch to ping your Lambda, start by creating rule (Cloudwatch -> Rules) and have it run every 5 minutes:

    enter image description here

    Then, have it run your Lambda:

    enter image description here

    My Lambda in this example is named SnapshotHandler and it takes a small JSON object. Note that this calls the Lambda directly, not through an API gateway. That may or may not be what your Lambda code is expecting so you may need to update.

    If you want to call this Lambda via a HTTP/S API, you'll need to setup an SNS topic to publish the Cloudwatch event to and have the SNS topic call your API via HTTP. This is a bit more complicated but not terrible.

    All in all, you can do this but the cost is dependent on how many "normal" calls your API gets. At 1000000 calls per month a 3GB / 800ms Lambda is at about USD $33. At 10000000 it's nearly USD $400. But if you're getting that many calls (an average of about 230/second) it seems unlikely you need a heartbeat too.