Back to blog
Engineering 12 min read · Apr 22, 2026

How we built sub-100ms code sync over WebRTC

Walking through our LiveKit + SignalR stack, the failover model, and why we chose CRDTs over OT for shared editor buffers.

C
CodeLabs
// How we built sub-100ms code sync over WebRTC

The transport: LiveKit for media, SignalR for state

Most collab tools punt on this and use a single transport. We chose two — LiveKit for video/audio/screen, SignalR for everything else — and we don't regret it.

The split lets us optimise each pipe for what it actually carries. LiveKit handles the multi-megabit/second media path with SFU forwarding. SignalR carries small JSON deltas — typically under 200 bytes — and can survive a 5-second reconnect without breaking the room.

Why we picked CRDTs over OT

Operational Transform is the obvious choice if you're building shared editors. It's what Google Docs uses. It's what our first prototype used. And it broke us in week two.

The problem is that OT requires a central server to serialise operations. Our entire premise was peer-driven sync — clients sending deltas at each other through SignalR with the server as a thin relay. CRDTs are commutative by construction: any two clients applying the same set of edits in any order land at the same state. No central authority required.

The first OT bug we hit was a classic: two cursors edit the same line, both inserts, server reorders them, and one client ends up with “Hello world” while the other has “Hellrold w” — divergent, wrong, and no way to recover without a hard reset.

The failover that saved us at 11pm

In December our self-hosted LiveKit cluster failed during the EU evening peak. Forty-six rooms went silent. We had no fallback.

The fix: a health-monitor background service that probes the primary every 15 seconds and routes new connections to LiveKit Cloud after three consecutive failures. Existing rooms drain naturally; new rooms come up on the fallback in under a second.

Wrapping up

Three years in, the LiveKit + SignalR + CRDT stack is still the right call. The 95th percentile end-to-end edit latency is 78 ms; the 99th is 142 ms. Most of that is the speed of light.

C
CodeLabs