Hardware FixRecommendedDevice not working? Your driver may be the problemCheck updates for common hardware issues.Fix DriversHalloween DealsAmazon USHalloween week deals: useful picks before month-endAmazon US: current deals, useful picks and tech finds.Check DealsWindows FixRecommendedWindows errors stealing your time? Find the fix fastScan stability, cleanup and performance issues.Fix Now×
FREEDOM251

Freedom251 › Blog › Amazon SQS

How to Build a Resilient SQS–Lambda Pipeline with Dead-Letter Queues in Terraform

By Freedom251 Team · · 8 min read

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Use an Amazon SQS source queue to buffer work for a Lambda function, an event source mapping to poll the queue and deliver batches, and a separate dead-letter queue (DLQ) to contain messages that repeatedly fail. In Terraform, model the queues with aws_sqs_queue, connect them with aws_sqs_queue_redrive_policy, and attach the source queue to the function with aws_lambda_event_source_mapping. The reliability of this design depends on matching the queue’s visibility timeout to Lambda’s timeout and batching window, choosing whole-batch or partial-batch retries deliberately, and operating the DLQ as a place for investigation—not as automatic recovery.

How SQS, Lambda, and a DLQ work together

SQS is the event source; Lambda does not receive a direct push from the queue. A Lambda event source mapping polls the queue and invokes the function with batches of messages. The source queue buffers work while the function is busy or unavailable, while SQS visibility and redrive settings govern when messages can be received again and when repeatedly received messages move to the DLQ.

As an Amazon Associate I earn from qualifying purchases.

  1. Producer: sends work to the source queue.
  2. Event source mapping: polls the source queue and invokes the Lambda function with up to the configured batch size.
  3. Function: processes records and reports success or failure for the invocation—or, when configured, individual records.
  4. SQS: removes successfully handled messages; messages not successfully handled can become visible again after the visibility timeout.
  5. Redrive policy: moves a message to the DLQ after its receive count reaches the configured maxReceiveCount.

The source queue and Lambda function must be in the same AWS Region, though they can be in different accounts. The function’s execution role needs permission to read and delete messages from the queue. AWS documents the AWSLambdaSQSQueueExecutionRole managed policy as including the permissions Lambda needs to read a queue; validate the permissions and scope them appropriately for your environment. If the queue is encrypted, the execution role also needs kms:Decrypt on the relevant key. AWS’s Lambda configuration guidance, accessed 2026-10-04 (publication year not displayed), describes these requirements.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Terraform configuration for the queues and mapping

This example uses the HashiCorp AWS provider’s 6.19.0 resource model. It assumes a Lambda function already exists as aws_lambda_function.worker; add your own function code, execution role, and any required queue permissions. Pin the provider and check the documentation matching your selected version before applying, since provider arguments can change.

terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 6.19.0"
    }
  }
}

resource "aws_sqs_queue" "worker_dlq" {
  name = "worker-dlq"
}

resource "aws_sqs_queue" "worker_source" {
  name                       = "worker-source"
  visibility_timeout_seconds = 180
}

resource "aws_sqs_queue_redrive_policy" "worker_source" {
  queue_url = aws_sqs_queue.worker_source.id

  redrive_policy = jsonencode({
    deadLetterTargetArn = aws_sqs_queue.worker_dlq.arn
    maxReceiveCount     = 5
  })
}

resource "aws_lambda_event_source_mapping" "worker_from_sqs" {
  event_source_arn = aws_sqs_queue.worker_source.arn
  function_name    = aws_lambda_function.worker.arn
  batch_size       = 10

  function_response_types = ["ReportBatchItemFailures"]
}

The example’s maxReceiveCount of 5 is an initial choice, not a universal setting. AWS Lambda guidance recommends at least five receives for an SQS source queue; adjust the value to allow plausible transient failures time to recover without leaving poison messages in the source queue indefinitely. The example’s 180-second visibility timeout is illustrative only: choose it from the function timeout and batching window as described below.

HashiCorp’s current queue guidance prefers the dedicated aws_sqs_queue_redrive_policy resource over inline queue redrive-policy attributes for drift detection. The Terraform resource references wire the DLQ ARN into the source queue’s redrive policy and the source queue ARN into the event source mapping.

How to choose the visibility timeout and batch settings

Set visibility timeout from the Lambda timeout

Visibility timeout is the period during which a received SQS message is hidden from other receives. If Lambda cannot finish successfully, the message may become visible again when that period expires. AWS recommends setting the source queue visibility timeout to at least six times the Lambda function timeout. If the mapping uses a nonzero batching window, add that window to the recommendation: at least six times the function timeout plus the batching window. Lambda rejects creation or update of a mapping when the function timeout exceeds the queue visibility timeout. The six-times guidance is an AWS recommendation to account for retries and throttling, not a replacement for setting a realistic function timeout.

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

For example, if the function timeout is 20 seconds and the mapping’s batching window is 5 seconds, the AWS recommendation yields a source-queue visibility timeout of at least 125 seconds: (6 × 20) + 5. Set the function timeout and batching window first, then configure the queue accordingly. The SQS API documents a visibility-timeout range of 0–43,200 seconds (12 hours) and a default of 30 seconds; those are service values, not recommended settings for every workload.

Balance batch size, batching window, and payload limits

A larger batch can reduce invocation overhead, but it also changes how much work is grouped into an invocation and can increase processing time. A batching window lets Lambda wait briefly to gather records before invoking the function. Actual batch size may be below the configured maximum because the synchronous invocation payload quota is 6 MB and message metadata counts toward that payload. AWS Lambda documentation, accessed 2026-10-04 (publication year not displayed), lists these event-source limits:

Queue type Maximum configured batch size Additional limit or consideration
Standard SQS 10,000 records For a batch size greater than 10, the batching window must be at least one second. The 6 MB synchronous invocation payload quota can result in fewer records per invocation.
FIFO SQS 10 records The 6 MB synchronous invocation payload quota can result in fewer records per invocation; strict ordering can make failure handling consequential.

Do not assume Lambda will always deliver the configured maximum batch. Select a batch and window your handler can finish within its timeout, and validate behavior against the payload quota and the queue type.

What happens when a batch fails

Default behavior: retry the batch

By default, if the handler fails while processing a batch, the batch is treated as failed and its messages return to the queue after the visibility timeout. Records that the handler processed successfully in that invocation can therefore be processed again alongside the failed record. Lambda backs off and reduces allocated concurrency when the function returns an error; throttling follows a somewhat different backoff path. This behavior can amplify duplicate work if the handler is not designed to tolerate it.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Partial batch responses: retry only reported failures

Setting function_response_types = ["ReportBatchItemFailures"] on the event source mapping allows the handler to identify the failed message IDs so Lambda can retry those records instead of reprocessing successful records in the batch. This is not automatic per-record error detection: handler code must catch and classify record failures and return the required partial-batch response correctly. A malformed or incomplete response can undermine the intended retry behavior.

Partial batch reporting improves retry precision, but it also affects polling behavior. AWS notes that when this mode is activated, Lambda does not scale down message polling when invocations fail. Treat it as a throughput and failure-handling choice, not only a way to avoid duplicate processing.

Make message processing safe to repeat

Assume a record may be delivered more than once, including after an invocation did useful work but failed before the batch was acknowledged. Design application-side processing to tolerate duplicate attempts—for example, by ensuring that repeating an operation does not cause an unintended second effect. The right idempotency key and persistence approach depend on the workload; neither SQS nor the event source mapping chooses that application policy for you.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

How the DLQ redrive policy works—and how to operate it

The source queue owns the redrive decision. Its redrive policy names the DLQ ARN with deadLetterTargetArn and sets the receive threshold with maxReceiveCount. Once a message reaches that threshold, SQS moves it to the DLQ rather than leaving it to cycle indefinitely in the source queue. AWS’s SQS API documents a default maxReceiveCount of 10 when the attribute is omitted; that API default is not a production recommendation. AWS Lambda guidance recommends at least five receives, while the appropriate threshold depends on how long transient failures could reasonably take to clear.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

A DLQ contains messages for diagnosis and a deliberate recovery decision; it does not repair the handler or replay messages automatically. Put an operational path around it:

  • Alert on DLQ message growth so failures are visible rather than silently accumulating.
  • Inspect representative failed messages and logs to identify whether the cause is bad input, a code defect, a dependency outage, or a permissions/configuration issue.
  • Choose an explicit controlled replay or discard process after correcting the cause, and consider whether replaying a message could repeat side effects.

SQS also supports a redrive allow policy on the DLQ to restrict which source queues can use it. Configure that control where appropriate for the account and queue design; do not treat a DLQ as implicitly isolated merely because it has a separate name.

Should a FIFO queue use a DLQ?

Choose the queue type based on whether strict ordering is a requirement, not just on a preference for one queue feature. A FIFO queue caps the Lambda event-source batch size at 10 records. More importantly, moving a repeatedly failing message to a DLQ can break the exact order of messages or operations: later work may proceed while the failed message is quarantined. AWS’s SQS DLQ guidance warns against using a DLQ with a FIFO queue when exact order must be preserved. If order is mandatory, decide explicitly how a poison message should block, be corrected, or otherwise be handled before enabling redrive.

Pre-deployment checks

  • Confirm the Lambda function and source queue are in the same Region; validate cross-account access separately if applicable.
  • Ensure the execution role can read and delete from the source queue, and can use the KMS key for decryption if the queue is encrypted.
  • Set queue visibility timeout to at least six times the function timeout, plus any nonzero batching window.
  • Check the batch size against the queue type, one-second batching-window requirement for standard batches above 10, and the 6 MB payload quota.
  • Choose whole-batch retry or implement and enable partial batch responses in both the mapping and handler.
  • Set a deliberate maxReceiveCount, monitor DLQ growth, and document who investigates and how messages are replayed or discarded.
  • Pin the AWS provider version and consult the matching provider documentation before changing resource arguments or applying.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Amazon SQSAWS Lambdadead-letter queuesServerless architectureTerraform

Leave a Reply

Your email address will not be published. Required fields are marked *

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Recommended PC Tool
Recommended PC Tool
Crashes, No Sound, or Screen Glitches?Free driver scan
PC Slower Than It Used to Be?Free scan - under a minute

Two free Windows tools

One Free Minute Could Fix That PC

Before you go - each of these free tools takes about a minute and tackles what quietly slows a Windows PC down.

Special offer. View Outbyte info, uninstall instructions, EULA, and Privacy Policy.