11

What is the difference between setting a Dead Letter Queue on an SNS Topic or on a Lambda function?

I was wondering, because if you set the DLQ on the SNS subscription, then that subscription message will fail over to DLQ when the Lambda (the subscriber) fails, correct? So in that scenario would setting the DLQ in these two places have the same effect?

I have set a DLQ on a SNS Topic Subscription, and it didn't "automagically" appear as the DLQ on the Lambda screen settings, so I assume there may be some difference?

SNS dead letter queue ref: https://docs.aws.amazon.com/sns/latest/dg/sns-dead-letter-queues.html

In general, message delivery fails when Amazon SNS can't access a subscribed endpoint due to a client-side or server-side error.

Lambda dead letter queue ref: https://aws.amazon.com/about-aws/whats-new/2016/12/aws-lambda-supports-dead-letter-queues/

AWS Lambda will write the event object invoking the Lambda function to this [DLQ] endpoint after the standard retry policy (2 additional retries on failure) is exhausted.

Lambda:

lamda dlq

SNS subscription:

enter image description here

Blundell
  • 75,855
  • 30
  • 208
  • 233

2 Answers2

10

The SNS DLQ is specific for SNS, the benefit here is that it also accounts for client errors such as the Lambda service being down. This will ensure if the Lambda service is down the messages can be replayed to it later, whereas if the DLQ is attached to the Lambda this would only account for a replay if the service is running.

However as I mentioned the SNS DLQ is only for notifications that are from SNS, whereas Lambda can support the DLQ from any incoming events. This means if you have multiple SNS topics, or an SNS topic and some SQS queues you only need to apply it to the Lambda itself.

Both services use SQS for their DLQs so the ingestion/retrieval from both would be identical. If you have a DLQ on both services then yes you might end up with 2 copies of the event/notification, however it is unlikely that you will get both as in theory would the Lambda endpoint acknowledges it SNS would treat as sent, this would then be Lambdas responsibility to add to the DLQ if it fails.

Chris Williams
  • 32,215
  • 4
  • 30
  • 68
  • That makes sense thanks, so things like DynamoDB events can be replayed by the Lambda DLQ. To clarify tho, is the SNS DLQ triggered if the Lambda crashes after receiving the SNS msg? i.e. SNS needs a successful response from the Lambda to confirm the SNS msg was consumed right? – Blundell Aug 23 '20 at 17:44
  • The documentation for the Lambdas state "For asynchronous invocation, Lambda queues the message and handles retries. If Amazon SNS is unable to reach Lambda or the message is rejected, Amazon SNS retries at increasing intervals over several hours. For details, see Reliability in the Amazon SNS FAQ.". So effectively if the Lambda service fails or you reject via the callback it will retry and I would assume add to the DLQ of the SNS. – Chris Williams Aug 23 '20 at 17:47
  • Great, and I'd guess then that the Lambda having an uncaught exception thrown counts as a rejection as well. :+1: – Blundell Aug 23 '20 at 17:50
4

SNS DLQ and Lambda DLQ protect your workload from different failure modes. The former is for failed message delivery from a topic, whereas the latter is for failed function execution. You should use both simultaneously. Here more info: https://aws.amazon.com/blogs/compute/designing-durable-serverless-apps-with-dlqs-for-amazon-sns-amazon-sqs-aws-lambda/

Otavio Ferreira
  • 755
  • 6
  • 11
  • yes but there is overlap, an SNS queue can notify that msg delivery failed if the Lambda crashed. So if you set both, you'd get two dead letters (which isn't a complete bad thing, but should be known). – Blundell Aug 14 '21 at 10:35
  • Not really. These two failures modes are mutually exclusive. Thus, either your SNS delivery fails (which the SNS DLQ captures) or your Lambda execution fails after accepting the SNS delivery (which your Lambda DLQ captures). That’s why I recommend having both the SNS DLQ and the Lambda DLQ configured. – Otavio Ferreira Aug 15 '21 at 15:49
  • I thought delivery of a msg is accepted after successful execution – Blundell Aug 15 '21 at 18:10
  • No. The SNS delivery to Lambda is asynchronous. Thus, the SNS delivery can succeed, and then the Lambda execution can fail. – Otavio Ferreira Aug 15 '21 at 20:18
  • From the docs: "If you're using Amazon SQS as an event source, configure a dead-letter queue on the Amazon SQS queue itself and not on the Lambda function." https://docs.aws.amazon.com/lambda/latest/dg/invocation-async.html#invocation-dlq – Ryan Collingham Nov 21 '22 at 11:02