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 ReceiveMessage is 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 ReceiveMessage requests 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.