Definition
- Short polling – the client sends an HTTP request every few seconds; the server responds immediately, usually with nothing new; simple but wasteful at scale.
- Long polling – the client sends a request and the server holds it open until data is ready or a timeout; reduces empty responses but each update costs a full HTTP cycle.
- SSE (Server-Sent Events) – a one-way server-to-client stream over a single long-lived HTTP connection; the browser's
EventSourceAPI reconnects automatically. - WebSocket – an HTTP upgrade to a full-duplex channel over one TCP connection; both sides send messages freely with minimal per-message overhead.
Rajesh is waiting for a transfer to clear at National Bank of India. Short polling is Rajesh phoning every ten seconds asking "is it done yet?" Long polling is Rajesh phoning and the clerk saying "stay on the line until it clears." SSE is the bank opening a one-way loudspeaker to Rajesh. WebSocket is a two-way open phone line where both Rajesh and the clerk speak whenever they like.
Understanding the Concepts
What is short polling?
Short polling is the simplest approach. The client sends a normal HTTP request every few seconds, and the server responds immediately. Most responses have nothing new. It is trivial to implement but wasteful at scale.
package com.bank.client;
// Client-side: poll every 5 seconds (simplified)
public class ShortPollingClient {
public void poll() {
while (true) {
TransferStatus status = restTemplate.getForObject(
"/api/v1/transfers/TXF-001/status", TransferStatus.class);
if ("COMPLETED".equals(status.status())) break;
Thread.sleep(5000); // wait 5 seconds, try again
}
}
}
10:00:00 GET /status → { "status": "PENDING" } ← empty
10:00:05 GET /status → { "status": "PENDING" } ← empty
10:00:10 GET /status → { "status": "PENDING" } ← empty
10:00:15 GET /status → { "status": "COMPLETED" } ← useful!
// 3 out of 4 calls were wasted
What is long polling?
The client sends a request and the server holds it open until data arrives or a timeout. When data arrives, the server responds and the client immediately opens a new request.
package com.bank.controller;
import org.springframework.web.context.request.async.DeferredResult;
@GetMapping("/api/v1/transfers/{id}/updates")
public DeferredResult<TransferStatus> longPoll(@PathVariable String id) {
DeferredResult<TransferStatus> result = new DeferredResult<>(30000L); // 30s timeout
updateQueue.register(id, result::setResult); // completed when data arrives
result.onTimeout(() -> result.setResult(new TransferStatus("PENDING")));
return result;
}
What is SSE (Server-Sent Events)?
SSE is a true one-way streaming push. The client opens one HTTP connection with Accept: text/event-stream, and the server keeps it open and writes events as they occur. The browser's EventSource API reconnects automatically.
package com.bank.controller;
import org.springframework.http.MediaType;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
@GetMapping(value = "/api/v1/prices", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
public SseEmitter streamPrices() {
SseEmitter emitter = new SseEmitter(0L); // no timeout
priceFeed.subscribe(price ->
emitter.send(SseEmitter.event()
.id(String.valueOf(price.id()))
.data(price)));
return emitter;
}
// Browser client – 3 lines, auto-reconnect built in:
const es = new EventSource('/api/v1/prices');
es.onmessage = (e) => render(JSON.parse(e.data));
es.onerror = () => console.log('Reconnecting...'); // automatic
What is WebSocket?
WebSocket is full-duplex. It begins as an HTTP request with Upgrade: websocket, the server responds 101, and both sides send messages freely with very low per-message overhead.
package com.bank.websocket;
import org.springframework.web.socket.*;
import org.springframework.web.socket.handler.TextWebSocketHandler;
public class TradingHandler extends TextWebSocketHandler {
@Override
protected void handleTextMessage(WebSocketSession session, TextMessage message) {
// Client sent an order → process and send fill back
Order order = parse(message.getPayload());
Fill fill = matchEngine.execute(order);
session.sendMessage(new TextMessage(toJson(fill)));
}
}
How do the four techniques compare? (comparison table)
| Feature | Short Polling | Long Polling | SSE | WebSocket | |---|---|---|---|---| | Direction | Client → Server | Client → Server | Server → Client | Both ways | | Connection | New per poll | Held per update | One persistent | One persistent | | Wasted calls | Many | Few | None | None | | Auto-reconnect | N/A | Manual | Built-in | Manual | | Binary support | No | No | No (text only) | Yes | | Complexity | Lowest | Low | Medium | Highest | | Infrastructure | Standard HTTP | Standard HTTP | Standard HTTP | WebSocket-aware |
When should you use each?
Use the least powerful technique that meets the need. If the server only pushes to the client, SSE is simpler and more robust than WebSocket. If both sides must talk interactively, WebSocket is required. Polling is a fallback for simple cases or environments where streaming is blocked.
Decision tree:
Is the client sending data back in real time?
Yes → WebSocket (chat, trading, collaboration)
No → Is the server pushing updates?
Yes → SSE (notifications, tickers, dashboards)
No → Short polling or long polling (simple status checks)
What are common mistakes?
The most common mistake is using WebSocket for a one-way feed like a stock ticker, carrying the complexity of reconnection logic for something SSE handles automatically. Another mistake is short polling without a cap, flooding the server at scale.
// Wrong – WebSocket for a one-way price feed:
// Must implement reconnection, heartbeats, lifecycle management
// Correct – SSE for a one-way price feed:
@GetMapping(value = "/prices", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
public SseEmitter prices() { ... } // auto-reconnect built in
What should a senior engineer know?
A senior engineer matches the technique to the direction and latency of each feature. In banking, notifications and tickers are SSE. A trading terminal or support chat is WebSocket. A rarely changing status that tolerates delay uses polling. If a mostly-one-way feature needs an occasional client action, that action is a normal REST call alongside the SSE stream, keeping the streaming channel simple.
Visual Overview
Short Polling: Client ──req──→ Server ──resp──→ (empty)
Client ──req──→ Server ──resp──→ (empty)
Client ──req──→ Server ──resp──→ (data!)
Long Polling: Client ──req──→ Server ......... (holds)
Server ──resp──→ (data!)
Client ──req──→ (repeat)
SSE: Client ──connect──→ Server
←──event1──
←──event2──
←──event3── (one-way stream)
WebSocket: Client ──upgrade──→ Server ──101──→
Client ←──msg──→ Server (both ways, freely)
Key Takeaway
These are four techniques for delivering updates from server to client, on a spectrum from simplest to most capable. Short polling asks on a fixed interval and is trivial but wasteful. Long polling holds the request until data arrives, reducing empty responses but still costing an HTTP cycle per update. SSE is a true one-way push where the server streams events over one persistent HTTP connection with automatic reconnection built into the browser's EventSource API. WebSocket is a full-duplex channel where both sides send freely after an HTTP upgrade, ideal for interactive two-way traffic.
At National Bank of India, each feature uses the matching technique. An old dashboard short-polled transfer status and flooded the server, so it moved to long polling. The stock price ticker and payment notifications are one-way, so they stream with SSE. The live trading terminal needs two-way messaging at low latency, so it uses WebSocket.
The principle is to use the least powerful technique that meets the need. If the server only pushes to the client, SSE beats WebSocket for simplicity and free reconnection. If both sides must talk interactively, WebSocket is required. Polling is a fallback for simple cases. If a mostly-one-way feature needs an occasional client action, that action is a normal REST call alongside the SSE stream.
Remember one sentence: match the update technique to the direction of the data: polling for simple checks, SSE for server push, WebSocket for two-way, and always prefer the simplest one that works.
---