skip to Main Content

I have a Node Lambda that I want to run each minute at the 45th second, so I built a script to invoke it once a minute.

const command = new InvokeCommand({
  FunctionName: "BalancerNoVPC",
  InvocationType: "Event",
});

const response = await client.send(command);

log.info("Req ID: " + response.$metadata.requestId);

This works fine, the invocation response has "StatusCode": 202 and logs show the invocation resolves with the request ID when it is supposed to do it

2024-12-06T10:15:45: INFO { m: 'Invoking Lambda' }
2024-12-06T10:15:45: INFO { m: 'Req ID: 3dc0a16d-a77d-4449-a1ff-92fbab6a929e' }
2024-12-06T10:15:45: INFO { m: 'Sleeping for 59916 ms' }

However, the execution takes a very long time when no cold start is involved. The first time it was invoked, the START event in CloudWatch was logged at 09:59:46.077Z and Init Duration was reported to be 736.98ms. It later timed out 30s later and exited, which is in line with what I’m expecting.

However, all subsequent invocation started more than 10s later than the expected.

2024-12-06T10:15:56.195Z START RequestId: 3dc0a16d-a77d-4449-a1ff-92fbab6a929e Version: $LATEST
2024-12-06T10:16:15.166Z END RequestId: 3dc0a16d-a77d-4449-a1ff-92fbab6a929e
2024-12-06T10:16:15.166Z REPORT RequestId: 3dc0a16d-a77d-4449-a1ff-92fbab6a929e Duration: 30000.00 ms   Billed Duration: 30000 ms   Memory Size: 128 MB Max Memory Used: 93 MB  Status: timeout

Even though the START is logged at the 56th second, it still exited only ~20s later and logged a duration of 30s. So it seems like the start time for the duration is correct, but the actual execution starts more than 10s late. I am fairly sure about this because this lambda invokes other ones (which are delayed roughly 10s as well) that consistently miss the beginning of the minute (and log errors accordingly). The soft limit for concurrent executions is 1000 and I’m not anywhere close (I’m running around 21 lambdas per minute).

I thought this could be due to asynchronous invocations, however I’m observing the same behaviour both with InvocationType: "Event" and InvocationType: "RequestResponse". Ironically the only time it executes on time is when it performs a cold start, from then on it’s always late.

2

Answers


  1. Chosen as BEST ANSWER

    As suggested in the comments, I added a timeout to exit gracefully and this eliminated the delay in subsequent executions. Cannot find any reference to how timeouts can affect future executions but apparently they do add several seconds of delay.


  2. TL;DR

    You are probably experiencing multiple executions of the code outside your handler within the same Lambda execution environment because of the timeout.

    Long version

    Let’s say we have the following code that will trigger a timeout depending on current second:

    const wait = async (waitMs) => {
      return new Promise((resolve, reject) => {
        setTimeout(() => {
          console.log({ waitMs });
          resolve();
        }, waitMs);
      });
    }
    
    const seconds = new Date().getSeconds();
    console.log({ seconds });
    const waitTime = seconds > 30 ? 3500 : 0;
    console.log({ waitTime });
    
    export const handler = async (event, context) => {
      console.log('Starting...');
      await wait(waitTime);
      console.log('Done.');
      return { statusCode: 200 };
    };
    

    And the logs for 6 invocations. The first 3 invocations ended with a timeout, while the rest did not.

    INIT_START Runtime Version: nodejs:22.v29   Runtime Version ARN: arn:aws:lambda:us-east-1::runtime:f494bf5385768c1a5f722eae90b6dd3d343c96ba7ec22b34f5c819e3e8511722
    2024-12-12T05:44:34.060Z    undefined   INFO    { seconds: 34 }
    2024-12-12T05:44:34.061Z    undefined   INFO    { waitTime: 3500 }
    START RequestId: fcf0c2b5-481d-4573-9815-ba5746e0408d Version: $LATEST
    2024-12-12T05:44:34.067Z    fcf0c2b5-481d-4573-9815-ba5746e0408d    INFO    Starting...
    END RequestId: fcf0c2b5-481d-4573-9815-ba5746e0408d
    REPORT RequestId: fcf0c2b5-481d-4573-9815-ba5746e0408d  Duration: 3000.00 ms    Billed Duration: 3000 ms    Memory Size: 128 MB Max Memory Used: 70 MB  Init Duration: 128.97 ms    Status: timeout
    
    2024-12-12T05:44:39.584Z    undefined   INFO    { seconds: 39 }
    2024-12-12T05:44:39.585Z    undefined   INFO    { waitTime: 3500 }
    START RequestId: 3ecf18d6-bfa9-461f-897f-5fef301fff30 Version: $LATEST
    2024-12-12T05:44:39.624Z    3ecf18d6-bfa9-461f-897f-5fef301fff30    INFO    Starting...
    END RequestId: 3ecf18d6-bfa9-461f-897f-5fef301fff30
    REPORT RequestId: 3ecf18d6-bfa9-461f-897f-5fef301fff30  Duration: 3000.00 ms    Billed Duration: 3000 ms    Memory Size: 128 MB Max Memory Used: 70 MB  Status: timeout
    
    2024-12-12T05:44:45.105Z    undefined   INFO    { seconds: 45 }
    2024-12-12T05:44:45.105Z    undefined   INFO    { waitTime: 3500 }
    START RequestId: 262641af-4b2a-44cc-b71a-023b58a08ce1 Version: $LATEST
    2024-12-12T05:44:45.124Z    262641af-4b2a-44cc-b71a-023b58a08ce1    INFO    Starting...
    END RequestId: 262641af-4b2a-44cc-b71a-023b58a08ce1
    REPORT RequestId: 262641af-4b2a-44cc-b71a-023b58a08ce1  Duration: 3000.00 ms    Billed Duration: 3000 ms    Memory Size: 128 MB Max Memory Used: 70 MB  Status: timeout
    
    2024-12-12T05:45:03.904Z    undefined   INFO    { seconds: 3 }
    2024-12-12T05:45:03.904Z    undefined   INFO    { waitTime: 0 }
    START RequestId: 6f894bed-f265-4975-a4cc-e694da68fee4 Version: $LATEST
    2024-12-12T05:45:03.924Z    6f894bed-f265-4975-a4cc-e694da68fee4    INFO    Starting...
    2024-12-12T05:45:03.925Z    6f894bed-f265-4975-a4cc-e694da68fee4    INFO    { waitMs: 0 }
    2024-12-12T05:45:03.925Z    6f894bed-f265-4975-a4cc-e694da68fee4    INFO    Done.
    END RequestId: 6f894bed-f265-4975-a4cc-e694da68fee4
    REPORT RequestId: 6f894bed-f265-4975-a4cc-e694da68fee4  Duration: 891.67 ms Billed Duration: 892 ms Memory Size: 128 MB Max Memory Used: 70 MB  
    
    START RequestId: 223295e5-55a4-47fe-adca-b26d8bc29f40 Version: $LATEST
    2024-12-12T05:45:06.284Z    223295e5-55a4-47fe-adca-b26d8bc29f40    INFO    Starting...
    2024-12-12T05:45:06.285Z    223295e5-55a4-47fe-adca-b26d8bc29f40    INFO    { waitMs: 0 }
    2024-12-12T05:45:06.285Z    223295e5-55a4-47fe-adca-b26d8bc29f40    INFO    Done.
    END RequestId: 223295e5-55a4-47fe-adca-b26d8bc29f40
    REPORT RequestId: 223295e5-55a4-47fe-adca-b26d8bc29f40  Duration: 2.94 ms   Billed Duration: 3 ms   Memory Size: 128 MB Max Memory Used: 70 MB  
    
    START RequestId: 8434328a-5fc2-45a4-a3ae-21f3fb03ebb7 Version: $LATEST
    2024-12-12T05:45:08.608Z    8434328a-5fc2-45a4-a3ae-21f3fb03ebb7    INFO    Starting...
    2024-12-12T05:45:08.609Z    8434328a-5fc2-45a4-a3ae-21f3fb03ebb7    INFO    { waitMs: 0 }
    2024-12-12T05:45:08.609Z    8434328a-5fc2-45a4-a3ae-21f3fb03ebb7    INFO    Done.
    END RequestId: 8434328a-5fc2-45a4-a3ae-21f3fb03ebb7
    REPORT RequestId: 8434328a-5fc2-45a4-a3ae-21f3fb03ebb7  Duration: 3.59 ms   Billed Duration: 4 ms   Memory Size: 128 MB Max Memory Used: 70 MB  
    

    What we can see from the logs:

    • Only first invocation did have a cold start.
    • First 4 invocations are executing the code outside the handler ({seconds: x} / { waitTime: 3500 }).
    • Only last 2 invocations are not executing the code outside the handler.

    Those logs are from the same log stream so we can assume that is coming from the same Lambda execution environment.

    So it’s possible that your code outside the handler was executed each time even though you were in the same Lambda execution environment.

    The fact that you fixed your timeout issue possibly results in a cleaner Lambda execution environment state after the first invocation. That could explain how it fixed your timeout delay for future warmed invocations.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search