Long Polling, WebSockets & SSE
IntermediateHTTP polling, long polling, WebSockets, and Server-Sent Events (SSE) are techniques for real-time client-server communication. Each has different trade-offs in complexity, scalability, and bidirectionality.
Overview
Standard HTTP is request-response — the client must ask the server for updates. For real-time features (chat, notifications, live dashboards), the server needs to push data to clients. Short polling (repeated requests every N seconds) is simple but wasteful. Long polling holds the connection open until the server has data — more efficient but still has reconnection overhead. WebSockets establish a persistent, full-duplex connection over a single TCP socket — ideal for bidirectional, low-latency communication (chat, gaming, collaborative editing). Server-Sent Events (SSE) provide a simpler, unidirectional push channel over standard HTTP — the server streams events to the client. SSE is easier to implement than WebSockets and works with HTTP/2 multiplexing, but only supports server-to-client communication.
Polling & Long Polling
Short polling sends requests at regular intervals. Long polling holds the request open until the server has data or a timeout occurs. Long polling reduces unnecessary requests but still has reconnection overhead.
// Short polling — simple but wasteful
setInterval(async () => {
const res = await fetch('/api/notifications');
if (res.data.length > 0) showNotifications(res.data);
}, 5000); // every 5 seconds — 80% of requests return empty
// Long polling — server holds request until data available
async function longPoll() {
try {
const res = await fetch('/api/notifications/poll', {
signal: AbortSignal.timeout(30000) // 30s timeout
});
const data = await res.json();
showNotifications(data);
} catch (e) {
// timeout or error — reconnect
}
longPoll(); // immediately reconnect
}
longPoll();
// Server side (Spring Boot)
@GetMapping("/api/notifications/poll")
public DeferredResult<List<Notification>> poll() {
DeferredResult<List<Notification>> result = new DeferredResult<>(30000L);
notificationService.registerListener(result);
return result; // response sent when data arrives or timeout
}WebSockets
WebSockets upgrade an HTTP connection to a persistent, full-duplex TCP socket. Both client and server can send messages at any time. Ideal for chat, gaming, and real-time collaboration.
// Client-side WebSocket
const ws = new WebSocket('wss://api.example.com/ws/chat');
ws.onopen = () => ws.send(JSON.stringify({ type: 'join', room: 'general' }));
ws.onmessage = (event) => {
const msg = JSON.parse(event.data);
displayMessage(msg);
};
ws.onclose = () => setTimeout(reconnect, 3000); // auto-reconnect
// Server-side (Spring Boot WebSocket)
@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {
@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint("/ws/chat").setAllowedOrigins("*").withSockJS();
}
@Override
public void configureMessageBroker(MessageBrokerRegistry registry) {
registry.enableSimpleBroker("/topic");
registry.setApplicationDestinationPrefixes("/app");
}
}
// Scaling WebSockets: sticky sessions (L7 LB) or Redis pub-sub
// for broadcasting across multiple server instancesServer-Sent Events (SSE)
SSE is a simple, unidirectional push channel over HTTP. The server sends a stream of events to the client. Simpler than WebSockets, supports auto-reconnect, and works with HTTP/2.
// SSE — server-to-client streaming
// Client
const source = new EventSource('/api/notifications/stream');
source.onmessage = (event) => showNotification(JSON.parse(event.data));
source.onerror = () => console.log('SSE reconnecting...');
// Auto-reconnects with Last-Event-ID header
// Server (Spring Boot)
@GetMapping(value = "/api/notifications/stream", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
public Flux<ServerSentEvent<Notification>> stream() {
return notificationService.getStream()
.map(n -> ServerSentEvent.<Notification>builder()
.id(n.getId())
.event("notification")
.data(n)
.build());
}
// Comparison
// Feature | Short Poll | Long Poll | WebSocket | SSE
// ──────────────────────────────────────────────────────────
// Direction | Client→Svr | Client→Svr| Bidirect | Svr→Client
// Latency | High | Medium | Low | Low
// Complexity | Low | Medium | High | Low
// Reconnect | Manual | Manual | Manual | Automatic
// HTTP/2 compat | ✅ | ✅ | ❌ (TCP) | ✅
// Binary data | ✅ | ✅ | ✅ | ❌ (text)Key Points to Remember
- 1Short polling is simple but wasteful; long polling is more efficient but still has reconnection overhead.
- 2WebSockets provide full-duplex, persistent connections — ideal for chat, gaming, collaboration.
- 3SSE is simpler than WebSockets for server-to-client streaming — auto-reconnect, works with HTTP/2.
- 4WebSockets require sticky sessions or a pub-sub backplane (Redis) for multi-server scaling.
- 5Choose SSE for notifications/dashboards; WebSockets for bidirectional real-time features.
Interview Questions
Sign in to ask AriaWhat is the difference between short polling, long polling, and WebSockets?
When would you use SSE instead of WebSockets?
How do you scale WebSocket connections across multiple servers?
Design the real-time messaging layer for a chat application.
How would you handle 1 million concurrent WebSocket connections?
Ask Aria about Long Polling, WebSockets & SSE
Your personal AI tutor — ask anything about this concept
Revision Status
Personal Notes
Sign in to save personal notes for this topic.
Discussion
Sign in to join the discussion.