This chapter is an outline. The curriculum, learning objectives and
structure are settled; the prose, diagrams and code are still being written.
What is below is the plan for the chapter, not the chapter.
SQS and AWS Lambda
The integration everyone reaches for first. The key fact, which the word "trigger" actively obscures: the Lambda service polls SQS on your behalf. SQS still does not push. Everything surprising about this integration follows from that one sentence.
1. What you will learn
- Explain precisely which component polls the queue
- Configure an event source mapping and predict its scaling behaviour
- Implement partial batch failure with
ReportBatchItemFailuresand know why the default is dangerous - Size visibility timeout relative to function timeout
- Decide when Lambda is the wrong consumer
2. Why this concept exists
- Lambda removes the poll loop, the worker pool, the scaling policy and the servers
- In exchange you accept its batching semantics, its concurrency model and its failure handling — none of which are obvious, and all of which have sharp edges
3. Beginner explanation
- You point Lambda at a queue and your function runs whenever messages arrive
- AWS does the polling for you
- If your function succeeds, the messages are deleted automatically
4. How it actually works
- The Lambda service runs pollers that call
ReceiveMessage, then invoke your function synchronously with a batch, then callDeleteMessagefor the batch on success - Default scaling: starts at 5 concurrent invocations, scales by up to +300/minute, ceiling 1,250 per event source mapping. Idle scales back to 5, optimising to 2
MaximumConcurrency(2–1,000) caps an event source; distinct from function reserved concurrency- Provisioned mode: dedicated pollers, min 2–200 / max 2–10,000, scales up to 1,000 concurrency/minute, up to 100,000 concurrent invokes. Mutually exclusive with
MaximumConcurrency - Batching: default batch size 10,
MaximumBatchingWindowInSecondsup to 5 minutes; invocation fires on window expiry, payload-size limit, or batch size. ⚠️ On a low-traffic queue Lambda may wait up to 20 s regardless of a smaller window - Failure, by default: the function throwing makes the entire batch visible again — messages that succeeded are reprocessed. This is the single biggest Lambda+SQS footgun
ReportBatchItemFailures: return{"batchItemFailures": [{"itemIdentifier": "<messageId>"}]}so only the listed messages return. Requires the ESM function-response type to be set- Visibility timeout must be ≥ function timeout; AWS guidance is at least 6×
- DLQ: configure it on the queue, not on the function — a function-level DLQ does not apply to SQS event sources
- FIFO: batches may span groups, order is preserved within a group, concurrency = min(active groups, MaximumConcurrency)
- Poller
ReceiveMessagecalls are billed SQS requests even when empty (Module 18)
5. Diagram
- Diagram 38 — sequence showing the Lambda service polling, invoking, and deleting (emphasising who does what)
- Batch failure: default whole-batch return vs
ReportBatchItemFailures - Scaling curve: 5 → +300/min → 1,250
6. Step-by-step flow
- Create the queue and the function
- Create an event source mapping (queue ARN → function)
- Lambda's pollers begin long-polling the queue
- Messages appear; a poller receives up to
BatchSize - Lambda invokes the function synchronously with the batch
- Success → Lambda deletes the whole batch
- Failure → whole batch returns, unless
ReportBatchItemFailuresnarrows it - After
maxReceiveCount, the queue's redrive policy moves messages to the DLQ
7. Configuration
BatchSize,MaximumBatchingWindowInSeconds,FunctionResponseTypes: [ReportBatchItemFailures]ScalingConfig.MaximumConcurrencyorProvisionedPollerConfig— not both- Function timeout, and queue visibility timeout ≥ 6× that
- Event filtering to discard uninteresting messages before invocation (and before paying for it)
- All numbers →
aws-facts.md§8
8. Production considerations
- Always enable
ReportBatchItemFailures. Without it, one bad message in a batch of 10 causes 9 needless reprocessings — and with a non-idempotent consumer, 9 duplicate side effects - Lambda can overwhelm your database. 1,250 concurrent functions × 1 connection each is 1,250 connections. Use
MaximumConcurrency, or RDS Proxy, or don't use Lambda - Throttling looks like failure: if the account concurrency limit is hit, invocations are throttled, messages return, receive counts climb, and the DLQ fills with perfectly good messages
- Cost crossover: at sustained high throughput, an always-on ECS consumer is usually cheaper than Lambda. Lambda wins on spiky and low-volume workloads
- Long-running work does not fit — the 15-minute function ceiling is hard. Use ECS or Step Functions
- Event filtering can cut invocation count and cost substantially on queues with mixed traffic
9. Common mistakes
- Believing SQS pushes to Lambda. Why → it explains nothing about scaling or batching. Instead → the Lambda service polls
- Not enabling
ReportBatchItemFailures. Why → whole-batch reprocessing. Instead → enable it and return the failed ids - Visibility timeout equal to function timeout. Why → no headroom for retries within the window. Instead → ≥ 6×
- DLQ configured on the function. Why → it does not apply to SQS event sources. Instead → redrive policy on the queue
- Ignoring downstream connection limits. Why → 1,250 concurrent functions. Instead → cap concurrency
- Using Lambda for 10-minute jobs. Why → 15-minute hard ceiling, and retries re-run the whole thing. Instead → ECS/EKS
10. Real-world example
- An image-processing pipeline: S3 → SQS → Lambda. Show the batch failure bug in its natural habitat, then the fix, then the point at which the workload outgrows Lambda
11. Interview questions
- 🟢 How do you trigger a Lambda function from SQS?
- 🟡 Which component polls the queue — SQS or Lambda?
- 🟡 What happens by default when one message in a batch fails?
- 🔴 How does Lambda scale for an SQS event source? Give the actual numbers.
- 🔴 Why must visibility timeout exceed function timeout, and by how much?
- 🔴 Your Lambda consumers are exhausting the database connection pool. What are your options?
- ⚫ When would you choose ECS over Lambda for an SQS consumer? Argue with cost and operational numbers.
12. Summary
- The Lambda service polls; SQS never pushes
- 5 → +300/min → 1,250 concurrency per ESM; provisioned mode goes much further
- Enable
ReportBatchItemFailures— the default is whole-batch retry - Visibility timeout ≥ 6× function timeout; DLQ goes on the queue
- Lambda suits spiky and short work; sustained high throughput usually belongs on ECS
Authoring notes
Terms defined in this module (defined once here, linked from everywhere else):
event source mappingReportBatchItemFailuresMaximumBatchingWindowInSecondsprovisioned modeMaximumConcurrencypartial batch response
Diagrams to build:
- Diagram 38 — who polls
- Partial batch failure comparison
- Lambda scaling curve
Code samples:
- Java Lambda handler returning
SQSBatchResponsewith failed item identifiers - Creating an ESM with batch size, window and
FunctionResponseTypes(CLI + IaC) - Configuring
MaximumConcurrencyand provisioned mode - An event filter pattern
Mandatory "why?" answers:
- Why does the whole batch retry when one message fails?
- Why must the visibility timeout be several times the function timeout?
- Why does 'SQS triggers Lambda' misdescribe what happens?
Facts to pull from _reference/aws-facts.md: 5 initial / +300 per min / 1,250 max, MaximumConcurrency 2–1,000, provisioned mode limits, batch window up to 5 min, 20s low-traffic caveat, 6x visibility guidance
← Previous: 18 — Cost · Index: Course home · Next: 20 — SNS + SQS Fanout →