ZNYThe Complete Guide to Building Real-Time Features with WebSockets in 2026 HTTP...
HTTP request-response is dead for modern apps. Whether it's collaborative editing, live dashboards, or gaming — users expect instant updates.
| Protocol | Latency | Browser Support | Complexity |
|----------|---------|-----------------|------------|
| WebSocket | ~0ms | Excellent | Medium |
| SSE | ~100ms | Excellent | Low |
| Long-Polling | ~500ms | Universal | Low |
| HTTP/2 Push | ~0ms | Limited | Medium |
WebSockets give you full-duplex, persistent connections.
const WebSocket = require('ws');
const wss = new WebSocket.Server({ port: 8080 });
// Room management
const rooms = new Map();
wss.on('connection', (ws, req) => {
const url = new URL(req.url, 'http://localhost');
const roomId = url.searchParams.get('room');
const userId = url.searchParams.get('user');
if (!rooms.has(roomId)) {
rooms.set(roomId, new Map());
rooms.get(roomId).set(userId, ws);
ws.roomId = roomId;
ws.userId = userId;
// Broadcast to room
broadcast(roomId, {
type: 'user_joined',
timestamp: Date.now()
ws.on('message', (data) => {
const message = JSON.parse(data);
broadcast(roomId, {
type: 'chat',
content: message.content,
timestamp: Date.now()
ws.on('close', () => {
rooms.get(roomId)?.delete(userId);
broadcast(roomId, { type: 'user_left', userId });
function broadcast(roomId, message) {
const clients = rooms.get(roomId);
if (!clients) return;
const payload = JSON.stringify(message);
for (const ws of clients.values()) {
if (ws.readyState === WebSocket.OPEN) {
ws.send(payload);
A single WebSocket server won't scale. Use Redis to broadcast across instances:
const redis = require('redis');
const redisSub = redis.createClient();
const redisPub = redis.createClient();
redisSub.subscribe('room:updates', (channel, message) => {
const { roomId, data } = JSON.parse(message);
broadcast(roomId, data);
function broadcast(roomId, message) {
// Publish for other instances
redisPub.publish('room:updates', JSON.stringify({ roomId, data: message }));
// Also broadcast locally
const clients = rooms.get(roomId);
if (!clients) return;
const payload = JSON.stringify(message);
for (const ws of clients.values()) {
if (ws.readyState === WebSocket.OPEN) {
ws.send(payload);
WebSocket connections drop. Handle it:
// Heartbeat to detect dead connections
setInterval(() => {
wss.clients.forEach((ws) => {
if (ws.isAlive === false) {
return ws.terminate();
ws.isAlive = false;
wss.on('connection', (ws) => {
ws.isAlive = true;
ws.on('pong', () => { ws.isAlive = true; });
Validate origins: Reject connections from unexpected origins
Authenticate on connect: Pass token in first message, reject if invalid
Rate limit messages: Prevent spam
Sanitize content: XSS in chat applications is serious
WebSockets enable real-time experiences that HTTP simply can't match. Start with a library like Socket.io for ease of use, scale with Redis when you need multiple servers, and always plan for disconnection.
Build your next real-time app on an all-in-one platform — includes WebSocket-ready hosting with auto-scaling.
This article contains affiliate links. If you sign up through the links above, I may earn a commission at no additional cost to you.
Get started with Systeme.io for free — All-in-one platform for building your online business with AI tools.