How WebSockets Scale at Production

The architecture behind distributed WebSocket infrastructure — from a single server to multi-region.

Scaling WebSockets is fundamentally different from scaling stateless HTTP. Persistent connections, state on the connection, and the need to broadcast to thousands of clients create specific architectural requirements. This is how Apinator solves them.

The Sticky Session Problem

Each WebSocket client maintains a persistent connection to one server node. Standard round-robin load balancing breaks subscriptions. Sticky sessions (or a pub/sub layer) are required.

Redis Pub/Sub Fan-Out

When you publish an event, Apinator fans it out to all nodes via Redis pub/sub. Each node delivers to its locally-connected subscribers. No direct node-to-node communication needed.

Ref-Counted Subscriptions

Apinator subscribes to a Redis channel only when the first local client joins. It unsubscribes when the last client leaves. This minimizes Redis traffic at scale.

Zero-Database Data Plane

WebSocket nodes (data plane) have no PostgreSQL dependency. Tenant config is cached in Redis. Adding more nodes is instant — no schema migrations, no shared state.

Multi-Region Topology

Deploy independent data planes per region. Users connect to the nearest node. Publish once to any region — the event reaches all regions via their own Redis pub/sub.

Presence at Scale

Presence tracking uses Redis hashes (member state) and sorted sets (heartbeat timestamps). Stale members are evicted automatically, even across server restarts.

Publish Across All Regions

One trigger() call delivers the event to every connected client in every region — via Redis pub/sub fan-out on each data plane.

publish.js
import { ApinatorServer } from '@apinator/server' // Control plane — single point of configuration const apinator = new ApinatorServer({ appId: 'your-app-id', key: 'api-key', secret: 'api-secret' }) // Publish once → fans out to all connected clients across all nodes await apinator.trigger('prices', 'tick', { symbol: 'AAPL', price: 182.45, timestamp: Date.now() }) // Internally: Redis PUBLISH realtime:{app}:prices → all subscribed nodes // Each node delivers to locally connected clients in-process // No direct node-to-node traffic, no broadcast storms

Frequently Asked Questions

Ready to get started?

Completely free, no credit card required. Deploy in minutes.