Search code examples
node.jsaws-lambdaaws-sdk-nodejs

High AWS Lambda Execution Duration with NodeJS AWS SDK v3 vs. v2


I am currently investigating an interesting problem I found with a NodeJS Lambda I am working on. The gist of it is, that the NodeJS AWS SDK v3 appears to be a lot slower for my use case than v2 of the SDK.

What could I improve to get the Lambda that uses v3 of the AWS SDK to be as "fast" as the Lambda that uses v2 of the AWS SDK.

To demonstrate this I created two very similar Lambdas. Both have 128MB of memory and use the NodeJS 14.x runtime. One uses v2 of the SDK, the other v3. Both only have minimal code, but very different execution duration.

Since v2 of the SDK is available in the runtime, I only had to deploy my index.js. For v3 I also have to deploy the node_modules, because v3 is not available in the runtime out of the box.

Furthermore, both get the same object from the same S3 bucket. The object itself is a simple text file with a size of 43 bytes.

Durations

v2: ~50-80ms     (Duration:   69.80 ms  Billed Duration:   70 ms Memory Size: 128 MB Max Memory Used: 90 MB)
v3: ~5500-7000ms (Duration: 6096.98 ms  Billed Duration: 6097 ms Memory Size: 128 MB Max Memory Used: 97 MB)

Those times are from Lambdas that are "hot".

Code with v2 SDK:

const AWS = require("aws-sdk");
const s3 = new AWS.S3();

exports.handler = async (event, context, callback) => {
    const params = {Bucket: "<bucket>", Key: "test.txt"};
    const data = await s3.getObject(params).promise();

    return callback(null, data.ContentLength);
};

Code with v3 SDK:

const { S3Client, GetObjectCommand } = require("@aws-sdk/client-s3");
const client = new S3Client();

exports.handler = async (event, context, callback) => {
    const command = new GetObjectCommand({Bucket: "<bucket>", Key: "test.txt"});
    const data = await client.send(command);

    return callback(null, data.ContentLength);
};

Since the v3 version is so much slower, I enabled X-Ray and checked where all the time is being lost (see image below). Apparently, the "Overhead" is the problem.

Lambda with NodeJS AWS SDK v3 and high overhead

The documentation has to the following to say about "Overhead":

Represents the work done by the Lambda runtime to prepare to handle the next event.

I have no idea what the runtime has to do here. Especially, because the method does not really do anything.


Solution

  • Thanks to Samrose Ahmed I got an answer to my question in an Github issue.

    I mistakenly used callback() with AWS SDK v3. The solution is to simply return a value or promise.

    const { S3Client, GetObjectCommand } = require("@aws-sdk/client-s3");
    const client = new S3Client();
    
    exports.handler = async (event, context) => {
        const command = new GetObjectCommand({Bucket: "<bucket>", Key: "test.txt"});
        const data = await client.send(command);
    
        return data.ContentLength;
    };