Stateless HTTP scales by adding servers; WebSocket does not
An HTTP API can scale by adding identical servers behind a round-robin LB; each request lives entirely within its handler. WebSocket connections are persistent — adding a server adds capacity for new connections, but does nothing to bridge messages between connections on different servers. To get cross-server fan-out, you need a message bus.
Redis Pub/Sub is the standard answer
Track 4 introduced this. In production, every WebSocket server publishes outbound messages to Redis and subscribes to receive them; local fan-out happens on each server. Add servers freely; capacity scales linearly until Redis itself becomes the bottleneck (which happens at very large scale — at that point, look at Redis Cluster or Kafka).
Socket.IO ships an adapter
If you are using Socket.IO, scaling is one line: client_manager=socketio.AsyncRedisManager(...). Every sio.emit() automatically bridges across all servers. You write zero pub/sub code.