Polling vs WebSockets¶
1. Decision¶
Choose Short Polling for simple low-frequency state checks; choose Long Polling for low-complexity server push where persistent TCP sockets or HTTP/2 are unsupported by infrastructure; choose WebSockets for high-frequency, bidirectional, low-latency real-time communication.
2. 30-Second Answer¶
Short Polling issues periodic HTTP GET requests (e.g., every 5 seconds). It is simple and stateless, but generates massive empty HTTP request/response overhead and high latency lag. Long Polling (Hanging GET) holds an HTTP connection open on the server until new data arrives or a timeout occurs, returning immediately when data is available. It eliminates empty polling requests but incurs repeated HTTP handshake overhead on every cycle. WebSockets establish a single, long-lived, full-duplex TCP connection, transmitting data in tiny 2 to 10-byte binary/text frames with sub-millisecond latency. WebSockets deliver maximum performance for high-frequency updates at the cost of managing stateful server socket connections.
3. Decision Matrix¶
| Option | Best For | Avoid When | Latency | Scalability | Consistency | Operational Complexity |
|---|---|---|---|---|---|---|
| Short Polling | Low-frequency status updates (e.g., check job status every 60s), low-traffic internal dashboards | High-frequency updates, real-time messaging, latency-sensitive applications | High (Latency lag equals polling interval e.g. 5s) | Low under high client counts (Server CPU thrashed by empty requests) | Weak (Delayed by polling interval) | Very Low |
| Long Polling | Moderate real-time updates when WebSockets/SSE are blocked by strict corporate firewalls | High-throughput bi-directional interactive applications (chat, gaming) | Low (Instant server response on event); High connection reset overhead | Medium (Hanging connections hold server worker threads unless async I/O used) | Medium | Medium |
| WebSocket | High-frequency bi-directional messaging, collaborative canvas, live gaming, chat | Simple low-frequency status checks, static content updates | Sub-millisecond (<5ms) | High for traffic bandwidth; Medium for server memory state | High (Real-time push) | High (State management, Pub/Sub cluster, heartbeat) |
4. Selection Rules¶
| Requirement | Best Choice | Rationale / Example |
|---|---|---|
| Check Asynchronous Job Status (Every 30s) | Short Polling | Client calls GET /jobs/123/status until status == COMPLETED |
| High-Frequency Real-Time Chat / Gaming | WebSocket | Sub-millisecond full-duplex framing eliminates HTTP header overhead |
| Real-Time Push Across Legacy Corporate Proxies | Long Polling | Fallback mechanism when strict proxies block WebSocket Upgrade headers |
| Minimize Server CPU & Empty HTTP Overhead | WebSocket or SSE | Avoid wasting CPU parsing 1KB HTTP headers for empty responses |
| Stateless Horizontal Scaling Behind Load Balancer | Short Polling | Every request is an independent HTTP call routed to any server instance |
| Serverless Lambda Real-Time Push | Long Polling / WS Gateway | API Gateway WebSocket or SQS/Long Polling integration |
5. Tradeoffs¶
- Stateless HTTP Simplicity vs Persistent Socket State
- Gain (Short Polling): No connection state; load balancers route requests cleanly to any node.
- Lose (Short Polling): 99% of requests return empty responses, wasting bandwidth and server CPU.
- Immediate Data Delivery vs Re-Connection Handshake Overhead
- Gain (Long Polling): Server responds immediately when data becomes available.
- Lose (Long Polling): Closing and re-opening HTTP connection on every event creates high TLS/TCP handshake churn.
- Microsecond Binary Framing vs Verbose HTTP Headers
- Gain (WebSocket): 2–10 byte frame headers vs 1KB+ HTTP headers per message.
- Lose (WebSocket): Stateful connections consume server RAM and OS file descriptors.
- Firewall & Proxy Traversal
- Gain (Polling): Standard HTTP/S requests pass through 100% of network firewalls and proxies.
- Lose (WebSocket): Strict proxies may drop long-lived WebSocket TCP streams.
- Infrastructure Complexity
- Gain (Short Polling): Standard REST backend code.
- Lose (WebSocket): Requires Redis Pub/Sub cluster backplane to route messages across multiple server nodes.
6. Interview Counter Questions¶
- How does Long Polling work internally on the server side (Async I/O / Event Loop vs Blocking Threads)?
- What is the network bandwidth waste comparison between Short Polling every 1 second vs WebSocket for 10,000 clients?
- How does HTTP/2 Server Push differ from WebSocket and Long Polling?
- How do socket connection limits (65,535 TCP ports) affect scaling 1 million WebSocket connections?
- What is the Thundering Herd Problem in Short Polling and how does Jitter solve it?
- How does Socket.io implement automatic fallback from WebSockets to HTTP Long Polling?
- What happens when a Long Polling request times out on an intermediate proxy (e.g., 30s timeout)?
- Why can Short Polling cause database connection pool exhaustion?
- When is Short Polling actually the correct engineering decision?
- How do you implement Long Polling using HTTP
Waitquery parameters (e.g., AWS SQS Long Polling)?
7. Gold Standard Answers¶
- On server miss, the handler does not block a thread; it registers a callback/promise on an event loop or Redis Pub/Sub listener with a timeout (e.g., 30s). When an event occurs or timeout fires, the callback resolves and returns the HTTP response.
- Short polling 10,000 clients every 1s sends 10,000 HTTP requests/sec (\(\approx 10\text{MB/sec}\) of empty HTTP headers). WebSocket sends initial handshakes once, then 0 bandwidth until an actual event occurs.
- HTTP/2 Server Push allows the server to send secondary static assets (CSS/JS) to the browser cache before the browser requests them. It is NOT designed for arbitrary application-level real-time data push.
- OS limits: 65,535 local TCP ports per client IP address. A single server with multiple virtual IP addresses and expanded file descriptors (
ulimit -n 1000000) can hold 1 million open TCP sockets using non-blocking epoll I/O. - Thundering Herd occurs when thousands of clients poll at the exact same second interval. Add random jitter (
interval = 5s + rand(0, 2s)) to spread polling requests evenly over time. - Socket.io initiates an HTTP Long Polling request first to verify connection viability and transport cookies/tokens, then issues an HTTP Upgrade request to seamlessly upgrade the connection to a WebSocket.
- Intermediate proxies (Nginx, AWS ALB) terminate idle HTTP connections after 30–60s. Long Polling servers must implement a timeout (e.g., 25s) to close the request cleanly with
HTTP 204 No Contentbefore the proxy drops it. - Each incoming short poll request acquires a database connection to check for new records. 10,000 concurrent polling clients exhaust DB connection pools, crashing the primary database with useless
SELECTqueries. - Short polling is correct for low-frequency checks (e.g., polling asynchronous video transcoding job status every 30 seconds), where building persistent WebSocket infrastructure adds unnecessary cost and complexity.
- AWS SQS
ReceiveMessageacceptsWaitTimeSeconds=20. SQS holds the API call open for up to 20 seconds, returning immediately when a queue message arrives, drastically reducing empty API billings.
8. Common Mistakes¶
- Short polling an API every 500ms instead of implementing WebSockets or SSE for real-time features.
- Implementing Long Polling on a thread-per-request web server (e.g., old Apache/Tomcat), exhausting server thread pools.
- Forgetting to set a server-side timeout on Long Polling requests, resulting in intermediate proxy
504 Gateway Timeouterrors. - Short polling a database directly without a caching layer, causing DB CPU thrashing.
- Polling without randomized jitter, creating massive synchronized traffic spikes on backend servers.
9. Keywords¶
Short Polling, Long Polling, WebSocket, Hanging GET, HTTP Upgrade, Bandwidth Overhead, Thundering Herd, Jitter, Epoll, File Descriptors, Socket.io, SQS Long Polling, HTTP 204 No Content.
10. Cheat Sheet¶
- Short Polling: Client sends HTTP GET every N seconds. (Use ONLY for low-frequency checks e.g. job status every 30s).
- Long Polling: Server holds HTTP request open until data arrives or timeout (25s) occurs. (Fallback for restricted firewalls).
- WebSocket: Single persistent full-duplex TCP socket (Sub-millisecond latency, high-frequency real-time messaging).
- Bandwidth: WebSocket = 2–10 byte frames vs Polling = 1KB+ HTTP headers per request.
- Thundering Herd Defense: Always add Random Jitter (
base_interval + rand()) to polling intervals. - Timeout Rule: Long Polling server timeout (e.g., 25s) MUST be shorter than proxy timeouts (30s) to avoid 504 errors.