Do these 3 things before closing this tab:
1Repair Windows errors before they cause bigger problems2Fix the driver behind crashes, sound loss and screen glitches3Clear out junk files and repair common Windows errorsA resilient SQS-to-Lambda pipeline comes down to four settings that must agree with each other: a queue visibility timeout of at least six times the function timeout, a source-queue redrive policy with maxReceiveCount of at least 5, partial batch responses (ReportBatchItemFailures) on the event source mapping, and a dead letter queue (DLQ) whose retention outlives the source queue. This guide shows how to wire those together in Terraform, why each value matters, and how to recover messages from the DLQ. The guidance is runtime-independent, so it applies equally to .NET, Node.js, Python or Java handlers. The Terraform listings are illustrative sketches built from the documented resource names, not a tested module, so size every number for your own traffic.
How the pieces fit together
Lambda’s SQS event source mapping polls the queue on your behalf, hands your function a batch of messages, and deletes them only when the invocation succeeds. If the invocation fails, the messages become visible again after the visibility timeout and are retried. When a message has been received more times than the redrive policy allows, SQS moves it to the DLQ. Resilience is the product of these three mechanisms being tuned so that they do not fight each other.
As an Amazon Associate I earn from qualifying purchases.
One placement rule trips people up: the DLQ belongs on the source queue (through its redrive policy), not on the Lambda function. A function-level dead-letter configuration applies to asynchronous invocations, which is not how an SQS event source mapping calls your code.
The queue and the function must be in the same AWS Region, although cross-account configuration is possible, according to AWS Lambda’s SQS event source mapping documentation.
#1 Best Overall
- 【Powerful Load-bearing】12U Network Rack Open Frame is constructed from durable cold rolled steel; Rack shelf supports enhance stability, wall-mounted capacity of 130lbs, the ground-mounted up to 260lbs
- 【Considerate Designs】Open-frame layout, including a top panel adding space, anti-slip shelf stops fixing devices and compatible racks for stack and expansion to meet requirements of home server rack
- 【Complete Accessories】A 12U open frame server rack, two ventilated shelves, four shelf stops, four velcro straps and a set of equipment mounting screws
- 【Versatile Application】Ideal for space-efficient multi-device setups in warehouses, retail, classrooms, offices and more; Excellent choices as AV Rack/IT Rack
- 【Effortless Setup】 Network Rack includes hardware, a comprehensive manual, mounting hole drilling template and an online assembly video to simplify setup
Get the timing right first
Visibility timeout: at least six times the function timeout
The function timeout must not exceed the queue’s visibility timeout. AWS goes further and recommends a visibility timeout of at least six times the function timeout, which leaves room for retries when Lambda is throttled. If you use a batching window on a standard queue, add the maximum batching window to that six-times figure (AWS Lambda docs). The general mechanics of the timeout are described in the Amazon SQS visibility timeout guide.
Worked example (an arithmetic illustration, not a recommendation for your workload): a 30-second function timeout gives a minimum visibility timeout of 180 seconds; add a 20-second batching window and it becomes 200 seconds.
maxReceiveCount: at least 5
AWS Lambda documentation states: “We recommend setting the maxReceiveCount on your source queue’s redrive policy to at least 5.” The reasoning is that throttling or transient errors can consume receives without a genuine processing fault, so a low count sends healthy messages to the DLQ prematurely. This is an AWS service recommendation, not proof that 5 is right for your application; poison messages that always fail will simply take longer to reach the DLQ as you raise it.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
Rank #2
- ADJUSTABLE DEPTH: 4-Post 42U open frame server rack with 4 vertical rails and adjustable mounting depth 22" to 40" (56,0cm to 101,7cm); Compatible with various servers / switches / data / AV and other IT equipment; EIA/ECA-310-E Compliant
- EASY ASSEMBLY: Mobile network rack with easy-to-follow assembly instructions and online video; Compact flat-pack shipping to avoid damage and facilitate installation; Total product height of 80.3in (204 cm) with casters, 78in (198cm) without casters
- COLD ROLLED STEEL: Durable 4 Post 19in open frame rack designed for ventilation with 42U mounting height and 1320lb (600kg) weight capacity (stationary); 3 install options included: casters, levelling feet, or base-plate to secure rack to the floor
- HARDWARE INCLUDED: Rolling computer/data rack includes cage nuts and screws to mount equipment, easy to read Units (U) and depth adjustment markings, cable management hooks for organization, and required assembly tools
- THE IT PRO'S CHOICE: Designed and built for IT Professionals, this 42U rack is backed for 2-years, including free lifetime 24/5 multi-lingual technical assistance
Report only the records that failed
By default, an error during batch processing returns the whole batch to the queue after the visibility timeout. Records that already succeeded are then processed again, and each retry also uses up receives toward maxReceiveCount. Enabling ReportBatchItemFailures on the mapping lets the function return only the identifiers of the failed messages; the rest are deleted (AWS Lambda docs, AWS Prescriptive Guidance).
The function returns a response in this shape, with one entry per failed message ID:
{
"batchItemFailures": [
{ "itemIdentifier": "<messageId of a failed record>" }
]
}
An empty list means the whole batch succeeded. Whichever runtime you use, catch exceptions per record rather than letting one bad message throw out of the handler, and collect the failing messageId values.
Rank #3
- Adjustable Depth: 23-40'' adjustable depth is used for servers and network equipment, ensuring enough space for AV equipment, components, and cabling, while allowing you to access ports and equipment from multiple sides.
- Strong Load Capacity: Ground-Mounted Load Capacity: 500 lbs, Wall-Mounted Load Capacity: 150 lbs. The av rack is made of carbon steel for better weldability performance and can help save space while meeting your need to place multiple devices.
- User-friendly Design: Ergonomic design makes the open frame av rack easier to use. The additional top panel is able to place other items with more available space. Roller design moves anywhere and anytime, is convenient, and is more energy-saving.
- Complete Accessories: We provide the accessories you need, including 2 x Pallets, 145 x M5*10 Cross Head Screws, 4 x Casters, 4 x M10*50 Expansion Screws,10 x M6*12 Cage Nuts, 1 x Grounding Wire, 1 x User Manual.
- Wide Application: The server rack wall mount maximizes the use of available space, suitable for retail venues, classrooms, offices, and other places where space is limited.
Make handlers idempotent
Even with partial responses, SQS can deliver a message more than once, and visibility timeouts can expire mid-processing. AWS Prescriptive Guidance recommends idempotent handling, so a repeated record produces the same end state: a conditional write keyed on message ID or a business key, an upsert instead of an insert, or a deduplication table. Idempotency is an application design task that Terraform cannot provide.
Dead letter queue behaviour you need to plan for
Retention
For standard queues, the original enqueue timestamp is preserved when a message moves to the DLQ, so the message’s clock keeps running. AWS says the DLQ’s retention should be longer than the source queue’s, or messages may expire before anyone can act on them. For FIFO queues, the timestamp is reset on transfer (Using dead-letter queues in Amazon SQS).
A related monitoring trap: for standard queues, the DLQ’s age metrics reflect time since the message was moved into the DLQ, not original enqueue time, so they should not be read as end-to-end message age.
Rank #4
- Universal 19” Rack Mount Compatibility – Perfect for pro audio, video, IT, and network gear. Compatible with mixers, routers, patch panels, servers, power amps, and more.
- Heavy-Duty Load Capacity – Built to support up to 550 lbs. Ideal for studio gear, DJ setups, server equipment, and AV components that demand serious stability.
- Robust Steel Frame & Design – Made with 1.5mm thick steel and weighs 36 lbs for maximum durability, reduced vibration, and long-term reliability in any setting.
- Mobile & Secure – Preinstalled with 3” industrial-grade caster wheels (lockable), making it easy to move and position your rack exactly where you need it.
- All-In-One Setup Kit Included – Comes with 34 rack screws (5mm & 6mm), a 1U blank spacer, and an assembly tool—ready for fast installation out of the box.
FIFO ordering
Moving a message to a DLQ can break exact ordering in a FIFO queue, because later messages in the group proceed while the failed one is set aside. If strict order is the whole point of the queue, decide in advance whether you accept that, and say so in the runbook.
Who may use the DLQ
The redrive policy on the source queue names the DLQ and the receive threshold. The redrive allow policy on the DLQ controls which source queues may point at it. The default permits source queues in the same account and Region; setting byQueue narrows this to a list of up to 10 specific source queue ARNs (AWS).
Quick wins for a faster PC:
Scan for outdated or missing drivers - takes under a minuteDriver Scan →Repair Windows errors before they cause bigger problemsFix Now →Terraform sketch
The HashiCorp AWS provider documents aws_sqs_queue and recommends the dedicated aws_sqs_queue_redrive_policy and aws_sqs_queue_redrive_allow_policy resources for managing those policies, rather than inline attributes (provider 6.19.0 docs). Using the separate resources also avoids circular references between the two queues. The sketch below assumes a function resource named aws_lambda_function.worker exists and is not a drop-in module; all numbers are placeholders chosen to satisfy the rules above.
Best Value
- Adjustable Depth: Depth adjustable from 23" to 40", this open frame server rack accommodates servers and network equipment while providing ample space for A/V gears and cable management. Enjoy easy access to ports and devices from multiple angles.
- High Weight Capacity: Supports up to 300 lbs on the floor (200 lbs when adjusted to maximum depth) and 200 lbs when wall-mounted (depth cannot be adjusted in wall-mounted mode). Made from carbon steel for superior welding performance and durability, this open frame rack is designed to save space while accommodating multiple devices.
- User-Friendly Design: Designed with your convenience in mind, this open frame server rack features an top shelf for extra storage and improved space utilization. The rolling casters let you move it effortlessly wherever you need it, making setup and movement a breeze.
- Widely Applicable: Maximize your space with this adaptable open frame server rack, designed to make the most of every inch. Ideal for retail spots, classrooms, offices, and any area where space is at a premium, it delivers practical solutions for your storage needs.
- Everything You Need: Our open-frame rack comes with fully equipped accessory kit for easy setup and secure installation: 2 x Trays, 4 x Casters, 1 x set of Screws, 16 x M6*12 Cage Nuts, 1 x Grounding Wire, 1 x Internal & External Hex Wrenches, and 1 x User Manual.
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 6.19" # pin deliberately; re-read the docs for the version you choose
}
}
}
locals {
function_timeout_seconds = 30
batching_window_seconds = 20
}
resource "aws_sqs_queue" "dlq" {
name = "orders-dlq"
message_retention_seconds = 1209600 # 14 days; must exceed the source queue's retention
}
resource "aws_sqs_queue" "source" {
name = "orders"
message_retention_seconds = 345600 # 4 days
visibility_timeout_seconds = local.function_timeout_seconds * 6 + local.batching_window_seconds
}
resource "aws_sqs_queue_redrive_policy" "source" {
queue_url = aws_sqs_queue.source.id
redrive_policy = jsonencode({
deadLetterTargetArn = aws_sqs_queue.dlq.arn
maxReceiveCount = 5 # integer, not a string
})
}
resource "aws_sqs_queue_redrive_allow_policy" "dlq" {
queue_url = aws_sqs_queue.dlq.id
redrive_allow_policy = jsonencode({
redrivePermission = "byQueue"
sourceQueueArns = [aws_sqs_queue.source.arn]
})
}
resource "aws_lambda_event_source_mapping" "orders" {
event_source_arn = aws_sqs_queue.source.arn
function_name = aws_lambda_function.worker.arn
batch_size = 10
maximum_batching_window_in_seconds = local.batching_window_seconds
function_response_types = ["ReportBatchItemFailures"]
}
Points worth checking against the docs for your provider version: the 6.19.0 queue documentation states that maxReceiveCount must be an integer in the encoded policy, and the event source mapping documentation lists ReportBatchItemFailures as the accepted value of function_response_types for SQS. Do not copy configuration between provider versions without re-reading the relevant page. Make the function timeout in the function resource reference the same local so the two cannot drift apart.
The batching window and batch size here are workload choices: a larger window cuts invocations but adds latency and lengthens the visibility timeout you need.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Permissions and encryption
The function’s execution role needs permission to receive and delete messages from the source queue and read its attributes; the Lambda documentation lists the exact actions. If the queue uses a KMS key, the role also needs decrypt access, and both the queue policy and the key policy matter. AWS’s least-privilege guidance for encrypted SQS queues explains how they interact. Remember that the DLQ must be encrypted compatibly if the source queue is. Key choice, account topology and role scoping depend on your threat model, so they are not prescribed here.
Recommended Free Tools
Alarm on the DLQ, then recover deliberately
A DLQ that nobody watches only hides failures. At minimum, alarm on the DLQ’s visible message count rising above zero, and treat the age metrics with the caveat above. Thresholds and notification routing depend on your service objectives.
resource "aws_cloudwatch_metric_alarm" "dlq_not_empty" {
alarm_name = "orders-dlq-not-empty"
namespace = "AWS/SQS"
metric_name = "ApproximateNumberOfMessagesVisible"
dimensions = { QueueName = aws_sqs_queue.dlq.name }
statistic = "Maximum"
period = 60
evaluation_periods = 1
threshold = 0
comparison_operator = "GreaterThanThreshold"
treat_missing_data = "notBreaching"
}
Redriving messages
Fix the cause of the failure first, or redriven messages will simply fail and return. AWS supports controlled DLQ redrive: start with a low custom velocity, then ramp up while watching source-queue depth and function health, so a backlog of replayed messages does not swamp downstream systems or trigger throttling. Built-in redrive does not filter or modify messages, so it moves everything it is given. If you need to inspect, repair or selectively replay, you need your own workflow, such as a small tool that reads the DLQ and re-sends chosen messages. See Configure a dead-letter queue redrive for the limits.
Decisions you have to make for your workload
| Decision | Option A | Option B | What decides it |
|---|---|---|---|
| Queue type | Standard: no ordering guarantee; preserves enqueue timestamp to the DLQ | FIFO: ordering; DLQ can break exact order; timestamp resets | Whether strict ordering is a hard requirement |
| Batch failure handling | Whole-batch retry: simplest, but repeats work | Partial batch responses: less rework, handler must report IDs | Cost of repeating a successful record |
| DLQ allow policy | Default: reusable by same-account, same-Region queues | byQueue: up to 10 named source ARNs |
Ease of reuse versus tighter restriction |
| Retention and redrive speed | Longer retention, slow redrive | Shorter retention, fast redrive | Your recovery objectives and downstream capacity |
Batch size, reserved concurrency and alarm thresholds also depend on measured traffic, which no general guide can supply; start from the AWS minimums above and adjust using real queue-depth and error data.
Quick Recap
Pre-deployment checklist
- Queue and function are in the same Region.
- Visibility timeout is at least 6 × function timeout, plus the batching window if one is set.
- The source queue’s redrive policy has
maxReceiveCountof at least 5, written as an integer. - The DLQ’s retention exceeds the source queue’s.
function_response_types = ["ReportBatchItemFailures"]is set and the handler returnsbatchItemFailures.- The handler is idempotent.
- The DLQ has an alarm and a documented redrive procedure, including an owner.
- If a KMS key is used, the execution role and key policies allow decryption.
- The AWS provider version is pinned and its docs reviewed.
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.
The Tool Desk
Outbyte Driver Updater FREEScan for outdated or missing drivers - takes under a minuteDriver Scan →Outbyte PC Repair FREEClear out junk files and repair common Windows errorsFree Scan →




