AWS Lambdas and memory state between executions

on
Launch the example stack on your AWS account and see it in action

AWS saves the state of your lambdas so global variables values can be passed/accessed between executions.

Lambda lifecycle

When you trigger a Lambda function on AWS, it creates a container to run your function. After the executions ends, that container is not destroyed – it is frozen until the next execution. That is what Amazon calls “The Freeze/Thaw Cycle” (more about it here).

When your functions is triggered again, the container is thawed and its memory state is exactly the same as the previous execution – if you saved anything outside the “handler” function, it will available for you again.

It can be bad – or good

If you are not aware of this feature you can start to see some strange behavior on your Lambdas if you are using global variables and it can cause intermittent errors that are difficult to debug.

On the other hand, you can use this behavior to help speeding up things, like caching results from queries or S3 objects in memory using global variables.

Example: simple execution counter

This code logs how many times this function was executed. Uses the “Launch Stack” button above to see it working.

let executionCounter = 0
exports.handler = function(event, context) {
  executionCounter++
  console.log(`Number of execution: ${executionCounter}`)
  return 'okay'
}

Here is what a CloudFormation template for deploying the Lambda would look like:

https://gist.github.com/maatthc/867c646314fa567cbc0cad9886783545
State is passed among 23 executions within 1 hour period

Taking advantage of this behavior

At work we have a real world example of how to use this to speeding up things.

The scenario is: we have a customer mapping table on Athena. That table doesn’t change very often , perhaps twice a year but querying that table on Athena takes from 2-4 minutes due the fact that Athena saves the results on S3 asynchronously and you have to fetch it from there.

To make it faster, before querying Athena directly, we check if a global array has the results: If the results already exist, we use if, otherwise we query Athena . Basically during the first execution of the Lambda we query Athena and load the results in that global array and give a time to live (TTL) so we can expires the values instead of using it indefinitely.

Leave a Reply

Your email address will not be published. Required fields are marked *