Learning/AWS SQS/12 — Long Polling
Intermediate 25 min read outline
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.

Long Polling

A one-line configuration change that cuts your SQS bill by an order of magnitude and lowers latency at the same time. Almost nothing in AWS offers both — which is why leaving it off is such a common and expensive default.

1. What you will learn

  • Explain the mechanical difference between short and long polling
  • Explain why short polling returns nothing on a non-empty queue
  • Set WaitTimeSeconds correctly at queue and request level
  • Quantify the cost and latency impact with real numbers
  • Write a polling loop that does not burn money when the queue is idle

2. Why this concept exists

  • Short polling queries a subset of SQS's servers and returns immediately — so it often returns nothing even when messages exist
  • A consumer that polls in a tight loop against an empty queue generates millions of billed requests per day for zero work
  • Long polling holds the connection open until a message arrives or the wait expires — fewer calls, and lower delivery latency

3. Beginner explanation

  • Short polling: "anything there? No? OK" — over and over, thousands of times a minute
  • Long polling: "tell me when something arrives, I'll wait up to 20 seconds"
  • Fewer questions, faster answers, much smaller bill

4. How it actually works

  • WaitTimeSeconds = 0 → short polling. > 0 → long polling. Max 20 seconds
  • Set at queue level (ReceiveMessageWaitTimeSeconds) or per request; the request-level value wins
  • Short polling samples a subset of servers (Module 03) — this is the reason for empty responses on a non-empty queue
  • Long polling queries all servers and returns as soon as any message is available, so it also reduces false empties
  • Long polling returns early the moment a message arrives — it does not wait out the full 20 s
  • NumberOfEmptyReceives is the CloudWatch metric that exposes the waste
  • ⚠️ In-flight limit interaction: at the in-flight quota, short polling returns OverLimit, long polling returns silently empty — a genuinely confusing debugging difference
  • Client-side timeout must exceed WaitTimeSeconds, or the SDK aborts the call before SQS answers

5. Diagram

  • Diagram 28 — sequence comparing short and long polling round trips
  • Diagram 29 — server sampling: why short polling misses messages

6. Step-by-step flow

  • Consumer calls ReceiveMessage with WaitTimeSeconds = 20
  • SQS holds the connection open
  • A message arrives → SQS returns it immediately
  • No message by 20 s → SQS returns an empty response
  • Consumer loops immediately — no sleep needed, the wait is the sleep

7. Configuration

  • Queue attribute ReceiveMessageWaitTimeSecondsset this to 20 on every queue
  • Per-request WaitTimeSeconds for the rare case where you want to poll and not wait
  • SDK socket/read timeout > WaitTimeSeconds
  • Range → aws-facts.md §2

8. Production considerations

  • Worked cost example: 10 consumers × short polling at ~20 req/s each ≈ 17.3 M requests/day ≈ $6.9/day ≈ $2,500/year for an idle queue. With long polling: a few thousand requests/day
  • Long polling reduces latency — a common misconception is that waiting adds delay. It does not: the response is immediate on arrival
  • Never add Thread.sleep() to a long-polling loop; the wait already throttles it
  • In a worker pool, each thread long-polls independently — the connection pool must be sized accordingly
  • The AWS console and some IaC defaults leave this at 0. Check every queue you inherit

9. Common mistakes

  • Leaving WaitTimeSeconds at 0. Why → 10–1000× more billed requests, plus false empties. Instead → 20 seconds
  • Adding a sleep between polls to 'save money'. Why → you have reinvented long polling badly and added latency. Instead → long poll
  • SDK timeout shorter than the wait. Why → every call aborts client-side; looks like a network problem. Instead → timeout > WaitTimeSeconds
  • Concluding 'queue is empty' from one empty short-poll response. Why → sampling. Instead → long poll, and treat emptiness as sustained
  • Using WaitTimeSeconds = 20 but MaxNumberOfMessages = 1. Why → you fixed the empty-receive cost and left the per-message cost. Instead → fix both (Module 13)

10. Real-world example

  • A team's SQS bill is 90% ReceiveMessage calls on a queue that handles 2,000 messages a day. Show the before/after on the CloudWatch NumberOfEmptyReceives graph

11. Interview questions

  • 🟢 What is long polling?
  • 🟢 What is the maximum long polling wait time?
  • 🟡 Why does short polling sometimes return no messages when the queue is not empty?
  • 🟡 How does long polling reduce cost and latency simultaneously?
  • 🔴 Your consumer sets WaitTimeSeconds = 20 but every call times out. Diagnose.
  • ⚫ Design the polling strategy for 50 consumers on a queue with bursty traffic — mostly idle, occasional 100× spikes.

12. Summary

  • WaitTimeSeconds = 20 on every queue. There is essentially no reason not to
  • Short polling samples a subset of servers → false empties
  • Long polling lowers cost and latency
  • Watch NumberOfEmptyReceives to find queues that are still short polling
  • Client timeout must exceed the wait time

Authoring notes

Terms defined in this module (defined once here, linked from everywhere else):

  • short polling
  • long polling
  • WaitTimeSeconds
  • ReceiveMessageWaitTimeSeconds
  • NumberOfEmptyReceives

Diagrams to build:

  • Diagram 28 — short vs long polling
  • Diagram 29 — server sampling

Code samples:

  • Setting ReceiveMessageWaitTimeSeconds at queue creation
  • A long-polling receive loop with correct SDK timeout configuration
  • A cost comparison harness that counts API calls both ways

Mandatory "why?" answers:

  • Why does short polling return empty responses on a non-empty queue?
  • Why does waiting longer make latency lower?

Facts to pull from _reference/aws-facts.md: WaitTimeSeconds max 20s, default 0, pricing per request, OverLimit vs silent empty at in-flight quota


Previous: 11 — Dead Letter Queues · Index: Course home · Next: 13 — Batch Processing