Busca en todas las páginas de la documentación
10 examples to choose between WebSocket, SSE, and long-polling - 7 basic and 3 intermediate.
These examples assume Node.js 24.18.0 and an HTTP server already running (Express 5, Fastify 5, or raw node:http).
npm install ws
npm install -D @types/wsFor implementation details, see ws Library, Server-Sent Events, and Socket.IO.
| Protocol | Direction | Transport | Reconnect | Complexity |
|---|---|---|---|---|
| WebSocket | Bidirectional | TCP upgrade | Manual | Medium |
| SSE | Server to client | HTTP stream | Automatic | Low |
| Long-poll | Server to client | HTTP request | Manual | Lowest |
Use WebSocket when:
- Client sends messages frequently (chat, gaming, collaboration)
- Latency must be < 50ms round-trip
- Bidirectional binary data (audio, file chunks)
- Connection state matters (presence, typing indicators)Use SSE when:
- Server pushes updates; client only sends via normal HTTP
- Live feeds (stock prices, sports scores, logs)
- Notification streams
- You want automatic browser reconnection// SSE response headers
res.writeHead(200, {
"Content-Type": "text/event-stream",
"Cache-Control": "no-cache",
Connection: "keep-alive",
});
res.write("data: {\"price\": 142.50}\n\n");EventSource API handles reconnection automaticallyUse long-polling when:
- Infrastructure blocks WebSocket (rare corporate proxies)
- Extremely simple notification need
- Fallback for Socket.IO (handled automatically)| Use case | Best choice | Why |
|---|---|---|
| Chat application | WebSocket | Bidirectional, low latency |
| Live log viewer | SSE | Server push, auto-reconnect |
| Collaborative editing | WebSocket | Bidirectional state sync |
| Stock ticker | SSE | One-way push, HTTP-friendly |
| Multiplayer game | WebSocket | Bidirectional, binary support |
| Email notification badge | SSE or polling | Infrequent, one-way |
WebSocket lifecycle:
1. Client sends HTTP Upgrade request
2. Server responds 101 Switching Protocols
3. Persistent TCP connection established
4. Frames exchanged bidirectionally
5. Either side sends close frame
6. Connection terminated
SSE lifecycle:
1. Client opens HTTP GET (EventSource)
2. Server streams text/event-stream
3. Connection stays open
4. Server sends data: lines
5. On disconnect, browser auto-reconnects// WebSocket: validate during upgrade
server.on("upgrade", (req, socket, head) => {
const token = new URL(req.url!, "http://localhost").searchParams.get("token");
if (!
import express from "express";
import { createServer } from "node:http";
import { WebSocketServer } from "ws";
const app = express();
const server = createServer(app);
const wss = new
import Fastify from "fastify";
const app = Fastify();
app.get("/events", async (req, reply) => {
reply.raw.writeHead(200, {
"Content-Type":
reply.raw for direct stream control in FastifyBefore 1000 concurrent connections, plan for:
- Sticky sessions (load balancer affinity)
- Redis pub/sub for cross-instance messaging
- Connection limits per instance
- Heartbeat/ping to detect dead connections
- Graceful shutdown (notify clients, close connections)SSE. Notifications are server-to-client. SSE gives auto-reconnect and works through HTTP infrastructure.
Yes. SSE works over HTTP/1.1 and HTTP/2. Disable proxy buffering in nginx.
When you need rooms, automatic fallback, and Redis adapter for scaling. See Socket.IO.
10k-50k idle connections depending on memory. Active fanout reduces this. Profile with your message patterns.
No. Use HTTP REST for CRUD. Add WebSocket/SSE only for real-time push requirements.
Stack versions: This page was written for Node.js 24.18.0 (Active LTS), npm 10+, TypeScript 5.6+, Express 5, Fastify 5, and NestJS 11.