CH 05

— Bulletin

◀ Return to log

Bulletin 04 · 2025-08-14

Zero-copy WebSockets in the browser

Binary frames, preallocated rings, and views instead of copies — how the ingest path stopped being the frame budget's biggest creditor.

Author
Alex Mercer
Published
2025-08-14
Reading time
2 min
Filed under
Networking
FIG.01 — Ingest cost per message across the rewrite8 week window

// Bulletin

The ingest path started life as JSON.parse in an onmessage handler, like everyone’s does. At forty thousand messages a second that is forty thousand strings decoded, forty thousand object graphs allocated, and a garbage collector doing steady-state demolition work behind the UI. The profiler said rendering was fine. The frames said otherwise — parsing was the tax every frame paid before drawing anything.

The first move was binary frames. The telemetry schema is fixed, so a message became a plain struct layout: known offsets, little-endian, no field names on the wire. A DataView over the received ArrayBuffer reads any field in place. Nothing is deserialized, because there is nothing to deserialize into — the buffer IS the data.

The second move was ownership. Each socket writes into a preallocated ring buffer sized for several seconds of burst; a message is a byte range in that ring, described by an offset and a length, never by a copy. Consumers get views. The renderer reads the fields it draws and ignores the rest. When the write head laps a range, that range is simply old — which is the contract: hold a view past one lap and it is your bug, and it shows up in soak tests, not in production.

“Zero-copy” is, strictly, one copy short of the truth — the browser copies the network payload into the ArrayBuffer it hands you, and that copy is not yours to remove. What you can remove is every copy after it, and those were the ones the collector was billing us for.

The chart in FIG.01 is the whole argument: ingest cost per message dropped by an order of magnitude, and the P99 frame time followed it down without the renderer changing at all. The fastest parser is the one that never runs.

// In this bulletin

  • — What JSON actually costs at 40k/sec
  • — Views over copies
  • — The ring buffer contract
Alex MercerSolid State · Colour Television
LIGHT
  • FB
  • X
  • LI
  • GH