*WebSockets

September 15, 2025

Concepts

  • Persistent connection, server push, multiplexing.

Scalability

  • Externalize state (shared store), sticky sessions or pub/sub broker.
  • Backplane (Redis, Kafka) for fan‑out; limit fan‑out explosion.

Connection lifecycle and heartbeats

  • Send periodic pings; drop dead connections to free resources.
  • Use connection IDs and presence sets (Redis SETs) to track who is online.

Alternatives

SSE for one‑way streams, emerging WebTransport/QUIC.

Code: Minimal WS server (Node.js, ws)

// language-javascript
import { WebSocketServer } from 'ws'
const wss = new WebSocketServer({ port: 8080 })

wss.on('connection', (ws) => {
  ws.on('message', (msg) => {
    // Broadcast to all clients
    for (const client of wss.clients) {
      if (client.readyState === 1) client.send(msg)
    }
  })
  ws.send('connected')
})

Code: Pub/Sub backplane (Redis)

// language-javascript
import Redis from 'ioredis'
const pub = new Redis(process.env.REDIS_URL)
const sub = new Redis(process.env.REDIS_URL)

sub.subscribe('room:1')
sub.on('message', (_, msg) => broadcastToRoom('1', msg))

function onClientMessage(roomId, msg) {
  pub.publish(`room:${roomId}`, msg)
}

Code: Presence tracking

// language-javascript
async function onConnect(userId, connId) {
  await redis.sadd(`presence:${userId}`, connId)
}
async function onDisconnect(userId, connId) {
  await redis.srem(`presence:${userId}`, connId)
  if ((await redis.scard(`presence:${userId}`)) === 0) {
    // last connection closed
    await publishUserOffline(userId)
  }
}

Testing and SLOs

  • Define max connections/node, p95 message delivery time, and acceptable loss.
  • Load test with connect/subscribe/publish patterns; monitor GC and file descriptors.