Real-Time Best Practices
A condensed summary of the 25 most important real-time practices for Node.js backends - drawn from every page in this section.
-
Pick protocol by directionality: SSE for server push; WebSocket for bidirectional - Real-Time Basics.
-
Auth on connection upgrade: Validate token before WebSocket handshake completes.
-
Never auth after messages flow: Reject unauthenticated connections immediately.
-
Ping/pong heartbeat every 30s: Detect and terminate dead connections - ws Library.
-
Clean up on disconnect: Remove from client sets; clear intervals and listeners.
-
Use rooms for targeted fanout: Not
io.emit()to every connected client - Socket.IO. -
Redis adapter before second instance: Socket.IO rooms break without it - Scaling Real-Time.
-
Redis pub/sub for raw ws scaling: Each instance fans out to local clients only.
-
Sticky sessions for polling transport:
ip_hashor K8ssessionAffinity. -
Disable nginx buffering for SSE:
proxy_buffering offandX-Accel-Buffering: no. -
Set SSE headers correctly:
text/event-stream,no-cache,keep-alive. -
Handle client reconnect: SSE auto-reconnects; WebSocket needs client retry logic.
-
Validate JSON messages: try/catch on
JSON.parsein message handlers. -
Rate-limit per-socket messages: Disconnect abusive clients.
-
Monitor
bufferedAmount: Close slow clients (backpressure). -
Connection limits per instance: Plan 10k-50k idle; less with active fanout.
-
Export connection count metric: Prometheus + HPA for autoscaling.
-
Graceful shutdown on SIGTERM: Notify clients, drain,
wss.close(). -
Use JSON message protocol with
typefield: Extensible message routing. -
Do not use WebSocket for CRUD: HTTP REST for requests; WS for push only.
-
Terminate TLS at proxy:
wss://at edge,ws://to Node. -
Test with real multi-instance setup: Two processes behind nginx.
-
Plan Redis HA: Sentinel or Cluster; pub/sub is a single point of failure.
-
Log connect/disconnect events: Include user ID and connection count.
-
Document protocol choice in ADR: Why SSE vs WebSocket for this feature.
FAQs
What is the most common real-time production bug?
Scaling to multiple instances without Redis adapter or pub/sub. Messages only reach clients on the same server.
SSE or WebSocket for notifications?
SSE. Notifications are server-to-client. Simpler infrastructure and auto-reconnect.
When do I need Socket.IO over ws?
When you need rooms, transport fallback, and built-in Redis adapter. Raw ws for minimal control.
How do I test real-time features?
WebSocket client in integration tests. For multi-instance, run two processes and verify cross-instance delivery.
How many connections before I need to scale?
Plan scaling architecture before 1000 concurrent connections. Implement Redis and sticky sessions before the second replica.
Related
- Real-Time Basics - protocol selection
- ws Library - raw WebSocket
- Socket.IO - rooms and adapter
- Server-Sent Events - SSE patterns
- Scaling Real-Time - multi-instance
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.