Lambda function invocation types

Lambda functions can be invoked in two different ways where the invocation path depends on the event source that triggers the Lambda function. These two mechanisms differ from each other, and I'll briefly cover them in this post.

Lambda is an important piece of the AWS serverless stack.

One of the advantages of using Lambda is that you don’t have to worry about provisioning and managing the server on which the function runs, because AWS does that for us.

Also, you only pay for what you actually use, which means that AWS charges you per function invocation, and it’s not necessary to maintain a server 24/7 if the code on it is not used. (It’s worth noting though that it’s easy to create horrendous bills with Lambda, and as such, it needs to be properly configured, but that’s a topic for another post.)

Lambda can also serve tens of thousands of concurrent invocations because it scales automatically, so you don’t need to worry about capacity issues. By default, Lambda supports 1000 concurrent invocations, but this is a soft limit, and it can be increased by submitting a request to AWS.

Creating Lambda functions is not very complicated, and I’ll refer to the linked post in the following sections. The name of the function, payload and response all come from there.

1. Invocation types

Lambda functions have two (or it can be three, see below) basic invocation types: synchronous or RequestResponse and asynchronous or Event type. The event source invoking the Lambda function decides which way the function will be invoked.

The third one is the DryRun type, which doesn’t execute the function but only tests if the caller has permission to do so. This invocation type doesn’t really occur in production, but it can be useful for testing, and I won’t go into more detail for this invocation type.

We can simulate both invocations using the CLI.

2. Synchronous (request-response) invocations

If you invoked the function following the post above, you triggered a synchronous or request-response invocation.

As a reminder, a synchronous invocation from the CLI looks like this:

aws lambda invoke --function-name my-lambda --payload fileb://input.json --region us-west-2 response.json

function-name can be anything nice, payload contains the input to the Lambda function as a JSON object, and response.json is the file in the same folder from which the command is executed where Lambda saves the response.

What makes the above function call synchronous is the invocation-type parameter, which is not present in the command. By default, the value of this parameter is RequestResponse, so the above CLI command is equivalent to this one:

aws lambda invoke --function-name my-lambda --invocation-type RequestResponse --payload fileb://input.json --region us-west-2 response.json

Request-response invocation means that Lambda invokes the function, and waits for the response, and returns it. The response can be an object (just like in the case above) or an error if the function can’t run for some reason.

After Lambda runs the function, it will return a 200 status code even if the function itself returns an error, so it’s your job to handle these situations.

In real life, many AWS services trigger request-response invocations.

One of the most often used service with Lambda is API Gateway, which can be configured as a proxy with Lambda being its backend. If this is the case, API Gateway will call Lambda synchronously, and simply passes the request over to Lambda. This will be the input (the payload in the above CLI invocation) to Lambda, which runs the Lambda function. The return value of the function invocation will be the response API Gateway will return to the caller of the API.

Other services like Application Load Balancer, Cognito or CloudFront also synchronously call Lambda.

3. Asynchronous invocations

When asynchronous or Event type invocation occurs, Lambda sends the event to a queue and returns a 202 status code.

We can simulate asynchronous invocation by making the value of the invocation-type parameter Event:

aws lambda invoke --function-name my-lambda --invocation-type Event --payload fileb://input.json --region us-west-2 response.json

The response should be something like this:

{
  "StatusCode": 202
}

Because the my-lambda function has been invoked asynchronously, response.json will be empty. Lambda returns an error if it can’t add the event to the queue.

Lambda manages the asynchronous invocation of the function. If it fails, then it will retry it two more times with some time-gap between the invocations. If the invocation is unsuccessful after three times, the event can be sent to a dead letter queue (DLQ), which is an SQS queue or an SNS topic. DLQ will be the topic of a later post.

A great example for a service calling Lambda asynchronously is S3. Event notifications, for example when an object is uploaded to an S3 bucket, can be configured to invoke a Lambda function, which can resize the image, or do something great to it.

Other event source examples for the asynchronous Lambda invocation are the already mentioned SNS, CloudWatch events or SES

4. Summary

Lambda has two basic invocation paths, synchronous (or request-response) and asynchronous (or event). The invocation type depends on the event source (usually a service) that calls the Lambda function.

For synchronous invocations, Lambda calls the function and returns the return value of the function as a response.

In the case of asynchronous invocations, Lambda sends the event to a queue and manages the invocations by automatically polling the queue to invoke the function three times in total.

Thanks for reading, and see you next time.