Queue-Based Load Leveling, DLQ, Retries and Idempotency on Serverless
A ticket counter sells fast; the kitchen cooks at a steady pace. The ticket rail between them is a queue. Serverless load leveling uses SQS (or similar) so a burst of API calls does not melt your workers. This chapter covers DLQ, retries, visibility timeout and idempotency — the four horsemen of safe async.
What you'll learn in this chapter
- Explain load leveling with a ticket-rail story
- Set visibility timeout vs Lambda timeout
- Design DLQ + maxReceiveCount + alarms
- Write idempotent consumers
- Link async-order project chapter
1. Everyday example: ticket rail
Sofia's cafe in Sofia (EUR) takes 40 orders when a tour bus arrives. The barista cannot froth 40 milks in 40 seconds. Tickets hang on a rail; they cook at a human pace. SQS is that rail for Lambda: API returns 202, workers pull when ready.
Build it hands-on in async order project. Messaging depth in SQS/SNS.
2. Why load leveling?
Why do we need this?
Without a queue, every spike becomes a concurrency spike, then throttles, then angry clients retrying harder. A queue turns a spike into lag — measurable, alarmable, drainable.
What is it?
Queue-based load leveling: producers enqueue work; consumers process at a controlled rate. DLQ holds messages that failed too many times. Idempotency makes at-least-once delivery safe.
3. Vertical path
4. Visibility timeout vs Lambda timeout
| Setting | Rule of thumb | |
|---|---|---|
| Lambda timeout | Slightly above p99 work duration | |
| SQS visibility timeout | Greater than Lambda timeout × batch worry factor (often ≥ 6× timeout for safety margin in labs, tune in prod) | Lambda timeout पेक्षा जास्त — tune |
| maxReceiveCount | 3–5 for most business messages | |
| batch size | Start 1–10; raise when safe |
Ravindra Bagale's Tip
If visibility expires while the worker still runs, another worker can pick the same message — double processing. Idempotency saves you; correct timeouts reduce pain.
5. How: wire intake + worker
How to do it (step by step)
- Create main queue + DLQ; set redrive maxReceiveCount.
- Intake Lambda: validate → SendMessage → 202 + id.
- Worker Lambda: parse → idempotent PutItem → success deletes message (ESM does it).
- Event source mapping with partial batch failure reporting on.
- Alarm: DLQ depth > 0; oldest message age high.
- Load test burst; watch concurrency and lag.
Create queue with redrive (shape)
aws sqs create-queue --queue-name sofia-orders-dlq --region ap-south-1
# then create main with RedrivePolicy pointing at DLQ ARN, maxReceiveCount=5
Meaning: Always create DLQ first so the ARN exists.
Send a message
aws sqs send-message --queue-url $Q --region ap-south-1 \
--message-body '{"orderId":"o-7","currency":"EUR","total":12.5}'
Meaning: Worker should create DynamoDB row once even if you send twice with same orderId (idempotent).
6. Idempotency patterns
Python: conditional put
# Concept: PutItem with ConditionExpression attribute_not_exists(orderId)
# First write wins; duplicate message returns ConditionalCheckFailed — treat as success
print("first -> wrote")
print("dup -> already exists -> ok")
Meaning: at-least-once delivery becomes exactly-once effect on your table.
Node: hash payload key
const crypto = require('crypto');
const key = (o) => crypto.createHash('sha256').update(JSON.stringify(o)).digest('hex').slice(0,16);
console.log(key({orderId:'o-7',total:12.5}));
Meaning: stable keys help dedupe when producers forget to send the same id.
7. Retry taxonomy
| Layer | What retries | You set |
|---|---|---|
| Client | HTTP calls | Backoff+jitter; honor 429 |
| SQS receive | After visibility | Timeouts + maxReceiveCount |
| Lambda async | On failure destinations | Prefer SQS trigger over naked async |
| SFN Retry | Per-state errors | Interval/backoff/maxAttempts |
8. Partial batch failure
When batch size > 1, one poison item should not rewind the whole batch forever. Report failures item-by-item so successes delete and poison heads to DLQ.
9. Lab: paper timeouts + optional queue pair
Do this in ap-south-1 (Mumbai) unless your org forbids it. Set a budget alert first.
How to do it (step by step)
- Write Lambda timeout and visibility timeout numbers for a 2s p99 worker.
- Draw maxReceiveCount path to DLQ.
- Optional sandbox: queue+DLQ+send+receive once.
- Alarm sketch: DLQ > 0 for 1 minute.
- Cleanup queues.
Cleanup (stop billing)
- Delete main queue then DLQ.
- Delete lab function and log group.
10. FIFO vs Standard for leveling
- Standard: higher throughput, best-effort ordering, duplicates possible.
- FIFO: order per message group, exactly-once processing within constraints, lower throughput.
- Aisha in Lagos uses FIFO for ledger postings (NGN); Standard for email notifications.
Get redrive + visibility
aws sqs get-queue-attributes --queue-url $Q --attribute-names All --region ap-south-1 --query 'Attributes.{V:VisibilityTimeout,R:RedrivePolicy,D:DelaySeconds}'
Meaning: Confirm visibility and redrive before load test.
11. Backpressure to producers
If lag grows without bound, stop accepting or shed load at API throttle. A queue is a shock absorber, not infinite disk for a broken worker.
12. Same pattern across industries
- Fintech (Aisha, Lagos): payment webhooks → SQS → Lambda; never block the bank callback thread.
- Ecommerce (Rohan, Pune): checkout API on API Gateway+Lambda; inventory fan-out on SNS.
- Healthcare (Mei, Singapore): appointment SMS via SNS; PHI stays in DynamoDB with fine-grained IAM.
- EdTech (Diego, São Paulo): nightly cleanup EventBridge → Lambda on student drafts.
- Logistics (Fatima, Casablanca): package scan events on EventBridge bus; Step Functions for customs saga.
- Media (Kenji, Osaka): S3 upload → Lambda thumbnails; fan-out to moderation + CDN invalidate.
- SaaS multi-tenant (Priya, Bengaluru): Cognito groups + DynamoDB partition per tenant.
- Gov portal (Omar, Amman): strangler fig — peel one PDF form route per sprint to Lambda.
13. Troubleshooting checklist
- Confirm region (ap-south-1 vs us-east-1 for CloudFront/ACM quirks).
- Check CloudWatch Logs for the function name and request id.
- Verify IAM execution role allows the API you call.
- For async: check DLQ depth and SQS age of oldest message.
- For APIs: curl -v and compare status, CORS headers, body.
- For workflows: open Step Functions execution event history.
- Re-read the linked deep chapter before reinventing a service.
- If cost spikes: check concurrency, retries, and provisioned capacity.
14. Common errors and fixes
Each row is a real mistake students and juniors hit. Read the fix before you panic.
| Error / symptom | Fix |
|---|---|
| Visibility < Lambda timeout | Raise visibility above timeout. |
| No DLQ | Add DLQ + maxReceiveCount. |
| Deleting messages before successful write | Write first; let ESM delete on success. |
| Ignoring ApproximateAgeOfOldestMessage | Alarm on age. |
| Batch size 10k with no partial failure | Enable partial failure; smaller batches. |
| Using queue as a database | Queue is transit; DDB/S3 for state. |
| Same idempotency key for different business intents | Key must include intent. |
| Poison message left in DLQ forever | Redrive after fix; ticket SLA. |
| FIFO when order does not matter | Standard is cheaper/faster. |
| No alarm on intake 5xx | Alarm + dashboard. |
15. FAQ
Q. Is SQS the only leveler?
Kinesis/MSK too; SQS is the default simple leveler.
Q. At-least-once vs exactly-once?
SQS is at-least-once; exactly-once effect via idempotency.
Q. Lambda event source vs polling?
Prefer ESM; no idle EC2 poller.
Q. How big a message?
256 KB limit; overflow to S3.
Q. Async order project?
build-async-order-api-with-sqs-lambda-dynamodb.
Q. Redrive?
Move from DLQ back to main after fix.
16. Interview Q&A (Beginner / Mid / Senior + MNC)
Q. Beginner: why queue?
Absorb spikes; protect workers.
Q. Beginner: DLQ?
Holds messages that failed too often.
Q. Mid: visibility vs timeout?
Visibility must exceed Lambda timeout.
Q. Mid: idempotency?
Same message twice → one business effect.
Q. Senior: partial batch failure?
Report per-item failures so successes commit.
Q. MNC: poison playbook?
Alarm, quarantine DLQ, fix, redrive with audit.
17. Tips in English, Marathi and Hindi
Ravindra Bagale's Tip (EN)
Tickets on a rail: 202 at the window, steady cooks, DLQ for burnt tickets, idempotent recipes.
Ravindra Bagale's Tip (MR)
Ticket rail: खिडकी 202, steady cook, DLQ, idempotent.
Tip (HI)
टिकट रेल: खिड़की 202, स्थिर कुक, DLQ, idempotent रेसिपी।
Try at home
- Write visibility and Lambda timeout for your worker.
- Name your idempotency key fields.
In short
- Start from a real story, then name the AWS services.
- Link existing chapters — do not copy their labs.
- Design for failure: retries, DLQ, idempotency, rollback.
- Measure before you buy provisioned concurrency or multi-region.
18. Architecture decision checklist
- Write the user journey in five bullets with no AWS names.
- Mark each step sync (user waits) or async.
- Name failure mode: retry, DLQ, compensate, or alert-only.
- Name the idempotency key for every write.
- Pick data store from access patterns (link DynamoDB modeling).
- Estimate monthly cost at 1x and 10x traffic (USD and INR).
- Confirm account concurrency and service quotas in ap-south-1.
- Decide auth: Cognito, IAM, Lambda authorizer, or none.
- Name on-call and which CloudWatch alarm pages them.
- Link the deep chapter you will not rewrite.
- Only then open console or IaC.
19. Copy-paste quick commands (read-only first)
# Region and identity
aws configure get region
aws sts get-caller-identity
# Lambda landscape
aws lambda list-functions --region ap-south-1 --max-items 20 \
--query 'Functions[].{N:FunctionName,R:Runtime,T:Timeout,M:MemorySize}' --output table
aws lambda get-account-settings --region ap-south-1
# API Gateway (HTTP APIs)
aws apigatewayv2 get-apis --region ap-south-1 --query 'Items[].{N:Name,Id:ApiId,Ep:ProtocolType}' --output table
# Queues and topics
aws sqs list-queues --region ap-south-1
aws sns list-topics --region ap-south-1 --query 'Topics[].TopicArn'
# Event buses and state machines
aws events list-event-buses --region ap-south-1
aws stepfunctions list-state-machines --region ap-south-1 --query 'stateMachines[].name'
# DynamoDB tables (names only)
aws dynamodb list-tables --region ap-south-1
Run these in a sandbox account. Prefer read-only IAM while learning.
20. More industry and stack stories
- Fintech (Aisha, Lagos, NGN): bank webhooks must return 200 fast — SQS absorbs spikes; ledger Lambda is idempotent on paymentId.
- Ecommerce (Rohan, Pune, INR): Black Friday — API Gateway throttle + SQS order intake; SNS fans inventory, email, analytics.
- Healthcare (Mei, Singapore, SGD): appointment reminders via SNS SMS; PHI only in DynamoDB with condition keys.
- EdTech (Diego, São Paulo, BRL): EventBridge nightly cleanup of draft quizzes; Lambda timeout 30s, not 15 min.
- Logistics (Fatima, Casablanca, MAD): package scans on custom EventBridge bus; Step Functions customs saga.
- Media (Kenji, Osaka, JPY): S3 → Lambda thumbnails; never write thumbs to the watched prefix.
- SaaS (Priya, Bengaluru, INR): Cognito groups + DynamoDB PK tenantId; one Lambda authorizer for all routes.
- Gov (Omar, Amman, JOD): strangler — peel one PDF form route per sprint from the monolith.
- Startup (Sofia, Sofia, EUR): start with Function URL for demos; move to HTTP API when partners need JWT.
- Retail (Luis, Mexico City, MXN): store POS sync via SQS FIFO when order matters; Standard when it does not.
- Python: handlers thin; put domain logic in plain modules for unit tests without Lambda.
- Node: prefer async/await; never block the event loop on sync DNS.
- Java: SnapStart for cold starts; keep dependencies lean.
- .NET: AspNetCoreServer for low-traffic tenants; watch package size.
- Go: single static binary; great for SQS workers.
- PHP: keep Laravel queues on ECS; Lambda for S3/webhooks glue.
21. Glossary (short)
| Term | Meaning |
|---|---|
| Cold start | First invoke pays init; later invokes reuse the env |
| Idempotency | Same request twice → same effect |
| DLQ | Dead-letter queue for failed messages |
| Choreography | Services react to events; no central conductor |
| Orchestration | Central workflow (Step Functions) directs steps |
| Fan-out | One event → many consumers |
| Fan-in | Many branches join before next step |
| Strangler fig | Peel routes from monolith gradually |
| Saga | Distributed tx via steps + compensations |
| Provisioned concurrency | Keep N envs warm; you pay for ready capacity |
22. Practice: explain out loud
- 60 seconds: everyday story for queue load leveling.
- 60 seconds: sync vs async with a checkout example.
- 60 seconds: when you refuse Lambda.
- 60 seconds: DLQ + idempotency in one breath.
- Record once; cut fillers; record again.
23. Safe lab hygiene
- Tag every lab resource with owner and expiry date.
- Set a monthly AWS Budget alarm in INR or USD before experiments.
- Prefer read-only commands first; mutate in a sandbox account.
- Delete queues, APIs, tables you created — DynamoDB and APIGW leave footprints.
- Never put production secrets in env vars or screenshots.
- Do not enable provisioned concurrency for a hello-world.
24. How this chapter links others
- Compute depth: Lambda.
- HTTP edge: API Gateway.
- Data modeling: DynamoDB.
- Messaging: SQS/SNS.
- Events: EventBridge.
- Workflows: Step Functions.
- Project chapters (build-*): worked assemblies — link, do not paste.
25. Myths to drop
| Myth | Reality |
|---|---|
| Serverless means zero servers | Servers exist; you do not manage them |
| Always cheaper than EC2 | Steady high load can favor EC2/Savings Plans |
| No Ops needed | You own IAM, data, alarms, cost, incidents |
| One Lambda per app is fine | Bounded contexts scale better |
| Queues are optional decoration | Queues are the load leveler and blast-radius wall |
26. Error budget thinking for serverless
If your monthly error budget is 0.1% on checkout, a fan-out that retries aggressively can burn the budget with duplicate emails while money stays correct. Separate business correctness SLOs from notification SLOs.
- Write two SLOs: money-correct and notify-delivered.
- Retries on money path: bounded + idempotent.
- Retries on notify path: best-effort + DLQ.
- Page humans on money DLQ; ticket on notify DLQ.
27. Regional notes (ap-south-1)
- Build labs in Mumbai (ap-south-1) unless your org mandates elsewhere.
- Some services launch first in us-east-1 — check feature availability.
- Data residency for INR fintech may require in-region only.
- Latency to end users in India usually favors ap-south-1.
28. Naming conventions that save incidents
# Suggested prefixes
# Lambda: pay-intake-prod, pay-worker-prod
# SQS: pay-orders.fifo / pay-orders-dlq
# SNS: pay-order-events
# EB bus: pay.domain
# SFN: pay-refund-saga
# DDB: pay-orders-prod
Include env (dev/stage/prod) and domain. Future you grepping CloudWatch will thank present you.
29. Pre-mortems (ten minutes)
- Imagine tomorrow headline: double charge in AED. What broke?
- Imagine DLQ depth 50,000 after a bad deploy. How do you drain?
- Imagine Cognito outage. Do APIs fail closed or serve read-only?
- Write answers in the runbook before go-live.
30. Currency and locale in examples
Rotate currencies in designs: INR, USD, EUR, AED, NGN, BRL, JPY, SGD. Rotate names: Aisha, Rohan, Mei, Diego, Fatima, Kenji, Priya, Omar, Sofia, Luis. This keeps mental models global — not one-country samples.
31. Worked failure timeline
- Message arrives; worker throws on bad JSON.
- Visibility expires or failure reported; receive count +1.
- After maxReceiveCount, message to DLQ.
- Alarm fires; human inspects body.
- Fix code; redrive; confirm DynamoDB.
32. Metrics that matter
- ApproximateNumberOfMessagesVisible — backlog.
- ApproximateAgeOfOldestMessage — SLA risk.
- NumberOfMessagesSent vs Deleted — leak detection.
- Lambda ConcurrentExecutions + Throttles — consumer side.
Revision, interview and comparison cards
Revise this lesson in a few minutes. Save the cards on your phone or download them as PNG files. The QR code on each card opens this lesson.








More cards: Ravi Sir's Cards.
Practice Tasks
Milan Furniture is a furniture business in Milan. Giulia Rossi looks after its IT and cloud work. They count money in EUR and run their AWS resources in the eu-south-1 Region. In the tasks below you do real jobs for them using what this lesson teaches. All names, account IDs, IP addresses and numbers are made up for practice.
0 / 16
Easy Ticket rail is queue — 1
Why: Metaphor.
What to do: Enter 1 if the ticket rail between counter and kitchen is a queue metaphor.
- Write down the numbers the task gives you.
- Work it out step by step on paper.
- Type only the final answer in the box.
- Click Check answer.
Easy Spike becomes lag — 1
Why: Effect.
What to do: Enter 1 if load leveling turns a spike into measurable drainable lag.
- Write down the numbers the task gives you.
- Work it out step by step on paper.
- Type only the final answer in the box.
- Click Check answer.
Easy Visibility > Lambda TO — 1
Why: Timing.
What to do: Enter 1 if visibility timeout should be greater than Lambda timeout.
- Write down the numbers the task gives you.
- Work it out step by step on paper.
- Type only the final answer in the box.
- Click Check answer.
Easy DLQ after failures — 1
Why: Safe.
What to do: Enter 1 if DLQ holds messages that failed too many times.
- Write down the numbers the task gives you.
- Work it out step by step on paper.
- Type only the final answer in the box.
- Click Check answer.
Easy List SQS queues
Why: CLI.
What to do: List SQS queues
- Read the task and decide which AWS service it is about.
- Write aws, then the service name, then the operation (the action word).
- Add each needed flag (--name) followed by its value from the task.
- Flags can be in any order. Click Check answer.
Easy Queue knobs YAML
Why: Config.
What to do: YAML: visibility: 60, max_receive: 3.
- Start from the top-level keys the task names.
- Indent child keys with 2 spaces (no tabs).
- Fill in each property with the value from the task.
- Click Check answer. Key order does not matter.
Easy Batch reduce cost — 1
Why: Cost.
What to do: Enter 1 if SQS batching can reduce Lambda invocations and cost.
- Write down the numbers the task gives you.
- Work it out step by step on paper.
- Type only the final answer in the box.
- Click Check answer.
Medium maxReceiveCount 3–5 — 1
Why: Config.
What to do: Enter 1 if maxReceiveCount of 3–5 then sends to DLQ.
- Write down the numbers the task gives you.
- Work it out step by step on paper.
- Type only the final answer in the box.
- Click Check answer.
Medium Conditional put — 1
Why: Write.
What to do: Enter 1 if idempotent PutItem often uses attribute_not_exists on the key.
- Write down the numbers the task gives you.
- Work it out step by step on paper.
- Type only the final answer in the box.
- Click Check answer.
Medium Partial batch failure — 1
Why: Batch.
What to do: Enter 1 if partial batch failure reporting stops poison items from rewinding whole batch.
- Write down the numbers the task gives you.
- Work it out step by step on paper.
- Type only the final answer in the box.
- Click Check answer.
Medium Oldest message age — 1
Why: SLA.
What to do: Enter 1 if high ApproximateAgeOfOldestMessage means consumers lagging.
- Write down the numbers the task gives you.
- Work it out step by step on paper.
- Type only the final answer in the box.
- Click Check answer.
Medium Idempotency YAML
Why: Write.
What to do: YAML: condition: attribute_not_exists, key: orderId.
- Start from the top-level keys the task names.
- Indent child keys with 2 spaces (no tabs).
- Fill in each property with the value from the task.
- Click Check answer. Key order does not matter.
Hard Intake returns 202 — 1
Why: API.
What to do: Enter 1 if async order intake API should return 202 Accepted.
- Write down the numbers the task gives you.
- Work it out step by step on paper.
- Type only the final answer in the box.
- Click Check answer.
Hard Queue not infinite disk — 1
Why: Anti.
What to do: Enter 1 if a queue is not infinite disk for a broken worker.
- Write down the numbers the task gives you.
- Work it out step by step on paper.
- Type only the final answer in the box.
- Click Check answer.
Hard Alarm on age + DLQ — 1
Why: Ops.
What to do: Enter 1 if you alarm on oldest age and DLQ depth.
- Write down the numbers the task gives you.
- Work it out step by step on paper.
- Type only the final answer in the box.
- Click Check answer.
Hard Delete lab same day — 1
Why: Hygiene.
What to do: Enter 1 if lab-spe-queue should be deleted same day.
- Write down the numbers the task gives you.
- Work it out step by step on paper.
- Type only the final answer in the box.
- Click Check answer.