Home > Blockchain >  Does AWS lambda (nodejs) share memory across different executions?
Does AWS lambda (nodejs) share memory across different executions?

Time:10-03

I have this lambda func that responds to Http event (get), sending the request I accept a pair of headers headerA and headerB.

Lambda is written in nodejs / typescript

On the implementation I have a global variable defined as a collection of objects:

let storage:{[myIndex :typeofHeaderA]? : storageDrivers } = {}

When I get a request I store a new instance of a Class I have into the above global var, on the "intended" index, if not yet present:

if(!storage[headerA]){
   storage[headerA] = new MyStorageDriver(headerB)
}

What I am experiencing is that, if considering two distinct request, close to each other:

1st request headerA1 headerB1

2nd request headerA1 headerB2

After the 2nd request storage[headerA1] will contain a instance of MyStorageDriver(headerB1) and not MyStorageDriver(headerB2)

As if on different request lambda execution , the global scope memory is shared or reused across request.

Is it something expected with AWS lambda or is it something else that lead me to this unexpected behaviour?

My current solution (and to double check this behaviour, is to change the global var like this :

      let storage:{[myIndex :typeofHeaderB]? :{
                      [myIndex :typeofHeaderA]? : storageDrivers }
                  } = {}

and then assign like this on requests:

     if(!storage[headerB]){storage[headerB]={}
     if(!storage[headerB][headerA]){
         storage[headerB][headerA] = new MyStorageDriver(headerB)
     }

CodePudding user response:

Yes it does happen and no, you shouldn't rely on it.

What happens is that each time there is a request for a Lambda to act, AWS backend looks to see whats available. If no current running container exists for that lambda, it will spin one up and create the container, the lambda, and then use it. Calling the lambda is called 'Invoke'. The process of starting up a container and initializing the lambda is called the Cold Start, and is a bit of a problem - it can take upwards of 15-30 seconds depending on the complexity of your lambda and layers

The next time AWS goes to Invoke that lambda, if an already existing container is still running, it will attempt to re-use that container. This is known as 'Keeping the Lambda Warm' so that it can be Invoked without the cold start, resulting in a much faster response time.

If it needs to respond to multiple requests (ie: scale) it will spin up additional containers. These are known as Concurrent Executions - if you view the metrics for your lambda you will find maybe thousands of Invokes - but only 3 or 4 Concurrent.

The logic that AWS uses on when to spin up and when to shut down conccurrent executions is based on predictive understanding of your traffic need whatever settings you have for provisioned capacity.

Across any invoke that is using an existing container, global variables will be maintained - because it is the same environment. This is why you are not supposed to use global variables for anything that may change during the execution of the lambda You cannot rely on concurrent executions and being in the same container as a previous execution, and you cannot rely on it not being one either.

  • Related