SQS is cheap until it isn’t. Real example from the wild: $500k in a weekend — and Amazon reportedly asked the team not to delete everything at once in certain regions, as it could impact the service. The usual culprit isn’t message volume; it’s how often you call ReceiveMessage when the queue is empty.
How SQS Billing Works
- You pay per request (SendMessage, ReceiveMessage, DeleteMessage, etc.), not per message.
- Standard queue: about $0.40 per million requests (after the 1M/month free tier).
- With Short Polling (default), every
ReceiveMessageis a billable request, even when the queue is empty. So polling empty queues burns money fast.
When the Bill Explodes: Short Polling
Default is Short Polling: ReceiveMessage returns immediately. If you have many workers or threads polling an empty (or nearly empty) queue, you pay for every single call.
Rough numbers (Standard queue, $0.40/million):
| Scenario | ReceiveMessage calls | Approx. cost |
|---|---|---|
| 1,000 workers, poll every 1s, empty queue, 1 weekend | ~216M | ~$86 |
| 1,000 workers, poll every 100ms, 1 weekend | ~2.16B | ~$864 |
| 10,000 workers, poll every 100ms, 1 weekend | ~21.6B | ~$8,640 |
| 10,000 workers, poll every 10ms, 1 weekend | ~216B | ~$86,400 |
| Large scale / many regions / burst → $500k | trillions of requests | $500,000 |
So a “small” change — more consumers, shorter poll interval, or a bug that spins up extra pollers — can multiply cost by orders of magnitude in a weekend.
Fix: Long Polling (receive_wait_time_seconds)
Use Long Polling so the API holds the connection and waits for messages instead of returning empty over and over.
- Set
receive_wait_time_seconds = 20(max 20 seconds). - The call stays open up to 20 seconds; if a message arrives, you get it; if not, one request covers that wait.
- Result: Far fewer
ReceiveMessagerequests for the same (or better) throughput. In practice people often see around 3x cost reduction or more, depending on traffic pattern.
Terraform example:
resource "aws_sqs_queue" "main" {
name = "my-queue"
receive_wait_time_seconds = 20 # Long Polling
# ...
}
When not to use it: If you need the absolute lowest latency and must get a response in milliseconds every time, Short Polling can be justified — but then expect to pay more and control scale and poll interval carefully.
Takeaways
- Short Polling (default) = pay per poll, including empty responses. At scale, this can lead to six-figure bills in days.
- Long Polling (
receive_wait_time_seconds = 20) = fewer requests, lower cost, often ~3x savings; accept up to ~20s wait per call. - Add billing alerts and anomaly detection so a runaway poller or misconfiguration doesn’t surprise you after the weekend.
For pricing details, see Amazon SQS pricing.