Skip to content

devlog

Three workers, one main thread

2026-05-14

The streaming pipeline is the engineering proof of concept. Why three workers, and why not one or seven.

The proof of concept has to render at 30 FPS on an integrated GPU while streaming and decoding splat chunks you've never seen before. The main thread can't do all of that, so the workers keep the canvas free.

The split is a fetch worker (HTTP, byte ranges, abort, backoff), a decode worker (gunzip, parse, transferable buffers), and a persist worker (OPFS sync-access-handle, LRU cache, eviction). The main thread orchestrates and renders. That's it.

Why not one worker? Decoding and persistence both block on disk. Share a thread and an aggressive write batch stalls a decode the next frame needs. I saw exactly that early on, so I split them.

Why not seven? Each worker adds a postMessage hop and a wire format, and every wire format is a versioned contract. Three workers is two contracts. A fourth buys one more parallelism point in exchange for another contract to maintain, which usually isn't worth it.

A streaming-host layer puts a priority queue on top so callers never see the worker boundary. The camera-direction priority boost and the trajectory prefetch both live in the host, not the workers, so the workers stay narrow and the orchestration stays in one place.