Search code examples
triggersaws-lambdadelayamazon-sqsaws-sam

How to trigger lambda with some delay when message published to SQS?


I have a lambda configured to be triggered when messages are published to SQS queue. Here is the SAM template for deployment.

  MyQueue:
    Type: AWS::SQS::Queue
    Properties:
        VisibilityTimeout: 180
        DelaySeconds: 90

  MyLambda:
    Type: AWS::Serverless::Function
    Properties:
      CodeUri: ../pathToCode
      Handler: index.handler
      Events:
        MySQSEvent:
          Type: SQS
          Properties:
              Queue: !GetAtt MyQueue.Arn

I am using DelaySeconds property of AWS::SQS::QUEUE which apparently doesn't work. My lambda get executed as soon as the message is published to queue. How can I put delay in it?


Solution

  • EDITED:

    There are 3 ways you can consider for delaying message delivery from SQS to Lambda:

    1. Configure DelaySeconds for the queue, so that new messages will be invisible to consumers (such as your Lambda) for a specific amount of time, up to 15 minutes
    2. Configure MaximumBatchingWindowInSeconds in your Lambda event source (trigger). Your Lambda can aggregate messages for the specified duration (up to 5 minutes), or until reaching the BatchSize (up to 10,000 messages, 10 by default). This option configures a maximal waiting time for messages, while for some messages there can still be no waiting at all (when the max window time / size is reached).
    3. Use a Step Functions state machine (with a Wait state), as proposed in the original answer. This gives the maximal flexibility, and the ability to wait up to 1 year.

    Original answer:

    The best solution is to use AWS Step Functions.

    The lambda triggered by the SQS should execute a state machine, where the first step is the required amount of sleep, and the second one is the lambda invocation.