# Amazon SQS

> The queue in front of Lambda. Natural back-pressure, nearly free when batched.

- Verdict: My default
- Vendor: AWS
- Layer: [APIs, queues and events](https://cloudlesslabs.com/stack/layers/api-events.md). Job: Queues and back-pressure
- Last reviewed: 18 October 2026, by Nicolas Dao (Cloudless Labs, Sydney)
- Web page: https://cloudlesslabs.com/stack/aws-sqs/. The whole stack in one file: https://cloudlesslabs.com/stack/brief.md

SQS in front of Lambda is the most boring, reliable pattern in my stack. Its only pain is configuration, and the three fixes above cover nearly every DLQ surprise I've seen.

## Use it when

- Anything that should survive spikes and failures between producers and Lambda.
- Batched ingestion (IoT, webhooks) into Postgres.

## Don't use it when

- Multi-step jobs where a failure in step 3 shouldn't rerun steps 1 and 2: look at Lambda durable functions.

## Pricing

Sydney: $0.40 per million requests (Standard), $0.50 (FIFO). A request carries up to 10 messages, so batching cuts the bill tenfold: 50M messages ≈ $6 batched, $60 unbatched.

## In my words: what hurts

- Retry and timeout settings have to be exactly right, or messages land in the DLQ.

## Gotchas, with fixes

- **Gotcha:** Messages reappear and get processed twice, or go to the DLQ, when the queue's visibility timeout is too close to the function's timeout.
  **Fix:** Set the visibility timeout to at least six times the function timeout.
- **Gotcha:** One bad message in a batch fails the whole batch, and the good messages retry too.
  **Fix:** Enable ReportBatchItemFailures and return only the failed message IDs.
- **Gotcha:** Messages bounce to the DLQ after too few attempts, or loop forever.
  **Fix:** Set maxReceiveCount deliberately (for example 3–5), and alarm on DLQ depth.

## Provisioning

Official Pulumi package · Official Terraform provider

@pulumi/aws sqs.Queue + lambda.EventSourceMapping.

## Instead, consider

- [Lambda durable functions](https://cloudlesslabs.com/stack/aws-lambda-durable-functions/index.md): Multi-step jobs with flaky dependencies.
- [Cloudflare Queues](https://cloudlesslabs.com/stack/cloudflare-queues/index.md): Only when both ends are on Workers.

## Worked examples

- [IoT ingestion into Postgres](https://cloudlesslabs.com/stack/guides/iot-ingestion/index.md): 5,000 devices send a reading every minute. Where does the money go?

## Where it fits

- [Background jobs and retries](https://cloudlesslabs.com/stack/use-cases/background.md): pick 1. The queue. Set visibility timeout to six times the function timeout.
- [Event-driven plumbing](https://cloudlesslabs.com/stack/use-cases/events.md): pick 2. Work: buffer, retry, dead-letter, and let Lambda take messages in batches.
- [Device and IoT data](https://cloudlesslabs.com/stack/use-cases/iot.md): pick 2. Buffer, then batch into Lambda.

## In The Stack Weekly

- [Week 43: Lambda durable functions](https://cloudlesslabs.com/weekly/2026-w43/index.md), worth a pilot

## Sources

- [Using Lambda with SQS](https://docs.aws.amazon.com/lambda/latest/dg/with-sqs.html)
- [SQS pricing](https://aws.amazon.com/sqs/pricing/)

## Related

- [APIs, queues and events](https://cloudlesslabs.com/stack/layers/api-events.md): every tool in this layer, with its verdict
- [The whole stack in one file](https://cloudlesslabs.com/stack/brief.md): every use case and tool, for questions that span many
- [Map of every Markdown file on cloudlesslabs.com, with what each one answers](https://ask.cloudlesslabs.com)
