Skip to content
AITroveRead. Build. Understand.
Make this comfortable

Socket Fanout, Backpressure, and Slow Consumers

Last updated: 5 Oct 20268 min read
tutorial
IntermediateBy AITrove Editorial

A server may publish one case event to hundreds of connections. Sending faster than a client can receive grows buffered bytes until the process runs out of memory or latency becomes useless. The browser WebSocket API exposes queued outgoing bytes, but it does not provide automatic application backpressure for all incoming work. Server libraries have their own buffering signals. The design needs a per-connection queue cap, a fanout budget, and a policy for slow consumers. Durable events can be recovered from a cursor after a disconnect; ephemeral hints may be dropped. Do not buffer unlimited private history inside the socket process.

Working case

A district incident produces 63 case updates per second while reviewer 47 uses a poor mobile connection. The server fans each update to 900 subscribers and keeps appending to reviewer 47’s queue. After a minute, that connection holds thousands of stale updates and delays current information. The service caps queued bytes and either coalesces replaceable case-summary updates or closes the slow connection with a recoverable cursor. It never drops a committed audit event silently while promising a complete history. The client reconnects, reauthorizes, and reconciles from durable case versions.

Implementation boundary

javascript
function shouldPauseSocket(bufferedBytes, nextBytes, budgetBytes) {
  return bufferedBytes + nextBytes > budgetBytes;
}
console.log(shouldPauseSocket(62000, 3000, 63000));
// Output: true

Measure queued bytes and message age per connection before enqueueing. Bound fanout concurrency so one burst does not monopolize the event loop or exhaust outbound writes. Choose a delivery class for each message: durable case change, replaceable latest summary, or ephemeral presence hint. A latest-summary message can supersede an older one for the same case; a durable comment event needs replay from storage if it cannot be sent. When the queue exceeds its budget, stop accepting more live messages for that connection and close or pause it according to the server transport. On the browser, inspect outgoing buffered bytes before sending high-frequency input. Rate-limit client messages and bound parsed payload size. Do not compress secrets together with attacker-controlled content without a separate risk review.

Cost and boundaries

Naive fanout is O(S) sends per event for S subscribers. If each connection queues B bytes, worst-case memory grows O(S × B), and a single unbounded slow client can retain far more than expected. A pub/sub broker helps distribute fanout but adds hop latency and still needs subscriber queue limits. Coalescing reduces bytes for replaceable state at the cost of intermediate visibility; it is invalid for history the product promises to preserve. Measure queue bytes, oldest queued age, disconnects for slow consumers, broker lag, event publish-to-display time, and replay volume after reconnect. Load-test with slow recipients, not only local fast sockets.

Failure trace

Hold reviewer 47’s network receive path while 900 other clients remain fast. Its queue must hit a bound without increasing memory indefinitely or delaying the others. Publish two replaceable case summaries and one durable comment; only summaries may coalesce. Let a browser send 47,000 tiny messages in a burst and enforce per-actor work limits. Disable compression and compare bandwidth and CPU before deciding if it is needed. Restart the fanout process after a durable event commits; the client should recover through replay or snapshot instead of relying on process memory.

Verification

  • Each connection has a measured queue-byte and age limit.
  • Only replaceable or ephemeral messages may be coalesced or dropped.
  • Fast clients stay responsive while one recipient is slow.

Practice drill

Set a 63-kilobyte per-connection queue budget and 900 subscribers for district 29. Publish 47 durable events, 63 replaceable summaries, and 29 presence hints while one client is throttled. Record maximum memory, oldest queued age, fast-client latency, dropped ephemeral hints, and the cursor used for the slow client’s recovery. Repeat with all clients fast to compare overhead. Make the recovery route enforce current tenant and record permission before returning any missed event.

Decision note

A slow socket receives bounded live work and recovers durable truth from storage, not an infinite in-memory queue.

Common Mistakes

  • Assuming send always transmits immediately.
  • Dropping durable history without a replay path.
  • Load-testing fanout only with fast local clients.

Related lessons

Realtime Connection and Event Delivery; WebSocket Handshake, Session, and Channel Authorization; Event Sequence, Replay, and Gap Reconciliation; Presence Expiry, Heartbeats, and Connection Drain; Stream Backpressure and Bounded Work; Data Channel Backpressure and Peer State.

Apply and check

Build Project: live permit case board and review Web Development: realtime delivery contracts quiz.

web-tech
web-development
Storage details