Realtime messaging
In-process fan-out hubs before you reach for a broker.
Realtime messaging
Business constraint
Users join rooms and receive messages with low latency. Early traffic fits on one box.
Naive v0
Each connection broadcasts by iterating a global map under one mutex. Or push every message through an external broker on day one.
Failure drill
Mutex contention caps throughput. Slow client blocks broadcast loop. Premature broker ops cost complexity before product-market fit.
Evolution path
Iteration 1
Per-room hubs with non-blocking send (drop or disconnect slow clients). Lab ws-fanout models this without a network.
Iteration 2
Add sticky sessions at the edge so a room concentrates on one instance while traffic is small.
Iteration 3
When multi-instance is required, introduce a pub/sub bus between hubs — keep client fan-out local.
Implementation cut
Prove room isolation and slow-consumer behavior in tests. Document the scale trigger for introducing a bus.
Numbers
Broadcast p99 inside a room. Max room size before split. Drop/disconnect rate for slow clients.
Pattern tags
Self-check
- Why per-room hubs beat one global lock?
- How do you handle slow consumers?
- When are sticky sessions enough?
- What changes with a cross-instance bus?
- What should you test without real WebSockets?
Walkthrough
Recordings will appear here when published. Until then, work the failure drill and lab locally — pause after each iteration and write the metric that moved.
Lab package: see /systems/labs/ws-fanout/.