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.
Search across all documentation pages
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_hash or K8s sessionAffinity.
Disable nginx buffering for SSE: proxy_buffering off and X-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.parse in 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 type field: 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.
Scaling to multiple instances without Redis adapter or pub/sub. Messages only reach clients on the same server.
SSE. Notifications are server-to-client. Simpler infrastructure and auto-reconnect.
When you need rooms, transport fallback, and built-in Redis adapter. Raw ws for minimal control.
WebSocket client in integration tests. For multi-instance, run two processes and verify cross-instance delivery.
Plan scaling architecture before 1000 concurrent connections. Implement Redis and sticky sessions before the second replica.
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.
Reviewed by Chris St. John·Last updated Jul 19, 2026