WebSocket vs SSE vs Polling: Real-Time Communication Compared
WebSocket, Server-Sent Events, and HTTP polling are three approaches to real-time web communication with different latency, direction, and complexity trade-offs.
At a Glance
| Feature | WebSocket | Server-Sent Events (SSE) | HTTP Polling |
|---|---|---|---|
| Direction | Bidirectional (full-duplex) | Server → Client (unidirectional) | Client → Server (request-response) |
| Protocol | ws:// / wss:// | HTTP (standard HTTP/1.1+) | HTTP |
| Latency | Low (milliseconds) | Low (milliseconds) | High (polling interval + latency) |
| Auto-Reconnect | Manual (library needed) | Built-in (EventSource auto-reconnects) | Manual (setTimeout loop) |
| Binary Data | Yes (binary frames) | No (text only — UTF-8) | No (text only) |
| Browser Support | Excellent (all modern browsers) | Good (all modern, no IE) | Universal |
| Server Complexity | High (persistent connection, protocol) | Low (standard HTTP response) | Very low (standard HTTP) |
| Scalability | Moderate (persistent connections) | Good (lightweight, HTTP-based) | Excellent (stateless HTTP) |
| Use Cases | Chat, gaming, collaborative editing | Live feeds, notifications, stock tickers | Basic refresh, legacy systems |
Key Differences
- Directionality: WebSocket is fully bidirectional — both client and server can send messages at any time. SSE is server-to-client only — the server streams events to the client, and the client uses standard HTTP requests to send data back. Polling is client-initiated — the client repeatedly asks the server for new data.
- Protocol: WebSocket uses its own protocol (ws://wss://) which requires a handshake upgrade from HTTP. SSE uses standard HTTP — it’s a long-lived HTTP connection where the server writes event data. Polling uses standard HTTP requests — no protocol changes needed.
- Latency: WebSocket and SSE both provide low-latency updates (sub-100ms) because the connection stays open. Polling latency equals the polling interval — if you poll every 5 seconds, a message can be delayed up to 5 seconds. Long polling (hold the request open until data arrives) reduces latency but increases server complexity.
- Auto-Reconnection: SSE has built-in reconnection via the EventSource API — if the connection drops, it automatically reconnects. WebSocket requires manual reconnection logic (libraries like Socket.IO handle this). Polling inherently retries because each poll is a new request.
When to Choose WebSocket
Choose WebSocket when you need bidirectional, low-latency communication — chat applications, multiplayer games, collaborative document editing, and live trading platforms. WebSocket is the only option that lets the server and client send messages freely in both directions. WebSocket also supports binary data (ArrayBuffer, Blob), making it suitable for applications that stream images, audio, or binary protocols. At DodaTech, WebSocket powers the real-time collaboration features in DodaZIP’s cloud file manager.
When to Choose SSE
Choose SSE when you need server-to-client streaming without bidirectional communication — live notifications, news feeds, stock price updates, or log streaming. SSE is simpler than WebSocket — it uses standard HTTP, has built-in reconnection, and works through most proxies and firewalls without special configuration. SSE is ideal for applications where the client only needs to receive updates from the server and can use standard HTTP requests (POST, PUT) to send data back.
When to Choose Polling
Choose polling for the simplest real-time scenarios — periodic data refresh, legacy system compatibility, or when server infrastructure doesn’t support persistent connections. Polling works everywhere with no special server requirements. Short polling (every few seconds) is fine for non-critical features like “check for new email.” Long polling (hold the HTTP response open until new data arrives) improves latency but increases server complexity.
Side by Side Code Example: Real-Time Notification System
WebSocket
// Server (Node.js with ws library)
const { WebSocketServer } = require("ws");
const wss = new WebSocketServer({ port: 8080 });
wss.on("connection", (ws) => {
console.log("Client connected");
// Server sends notifications
sendNotification = (msg) => ws.send(JSON.stringify(msg));
// Client can also send messages back
ws.on("message", (data) => console.log("Received:", data.toString()));
});
// Client
const ws = new WebSocket("wss://example.com");
ws.onmessage = (event) => {
const notification = JSON.parse(event.data);
console.log("New notification:", notification);
};SSE
// Server (Express)
app.get("/notifications", (req, res) => {
res.writeHead(200, {
"Content-Type": "text/event-stream",
"Cache-Control": "no-cache",
Connection: "keep-alive",
});
// Send notifications
setInterval(() => {
res.write(`data: ${JSON.stringify({ message: "New update" })}\n\n`);
}, 1000);
});
// Client (auto-reconnects!)
const source = new EventSource("https://example.com/notifications");
source.onmessage = (event) => {
const notification = JSON.parse(event.data);
console.log("New notification:", notification);
};HTTP Polling
// Server (Express) — standard endpoints
app.get("/api/notifications", (req, res) => {
const latest = getNotifications(req.query.lastCheck);
res.json(latest);
});
// Client — poll every 5 seconds
async function pollNotifications() {
const response = await fetch(`/api/notifications?lastCheck=${lastCheck}`);
const notifications = await response.json();
notifications.forEach((n) => console.log("New notification:", n));
lastCheck = Date.now();
}
setInterval(pollNotifications, 5000);All three deliver notifications to the client. WebSocket uses a persistent bidirectional connection with a custom protocol. SSE uses a long-lived HTTP connection with built-in reconnection. Polling makes repeated HTTP requests — simple but with latency proportional to the polling interval.
FAQ
Related Comparisons
REST vs GraphQL for API design. Express vs Fastify for Node.js frameworks.
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro