Global Variables in AWS lambda functions


Let’s assume the following AWS lambda handler written in python, built with the default sam init

import json

class Greeting():
    def __init__(self, greet):
        self.greet = greet

    def say_hello(self, name):
        if self.greet is None:
            return f"Hello {name}!"
        return f"{self.greet} {name}!"


greeting = None


def lambda_handler(event, context):
    global greeting

    query_string_params = event["queryStringParameters"]
    name = query_string_params["name"]

    if greeting is None:
        greeting = Greeting("Salut")

    if "greet" in query_string_params:
        greeting = Greeting(query_string_params["greet"])

    message = greeting.say_hello(name)

    return {
        "statusCode": 200,
        "body": json.dumps(
            {
                "message": message,
            }
        ),
    }

Here, we are initalizing a global variable named greeting which will be an object of the class Greeting. This class has a variable that can be called while initializing the object which is greet and another variable sent when calling say_hello function.

In the handler definition, we are checking if greeting is not initialized, then create a new object, another check if we can change the greet to ( hello , salut , hola … ), because there is no way to change the greet variable within the object we are creating it from scratch.

Till now everything is great, let’s say_hello and return the message in json.

To test this thing locally, let’s open our terminal and run sam build --use-container, then run sam local start-api, and leave this tab open.

To test the api let’s go through these steps:

Step 1: let’s run this command in another terminal

curl -X GET "http://127.0.0.1:3000/hello?greet=Hey&name=Adham"

Here we should expect the response message to be {"message": "Hey Adham!"} which really happens.

Step 2: make sure you didn’t close sam local start-api terminal and run the following command

curl -X GET "http://127.0.0.1:3000/hello?name=Adham"

Here we should expect the response message to be {"message": "Salut Adham!"}, while in fact it is {"message": "Hey Adham!"} !!!

Step 3: now go to the first terminal window/tab and close the local api then run it again. Then run the Step 2 curl command again. It will return {"message": "Salut Adham!"} as the Greeting is created from scratch.

So what is happening here ??

Global variables stay as long as the initialized container stays up ( it shutdowns the container if it remains inactive for certain period of time) or code is modified and redeployed. You should be cautious of what we are putting up as cache.

Caching global variables may be useful for quick responses and lazy loading objects of databases connections for example but in our case it breaks the flow.

Resources