Google Docs raised the baseline in 2006: simultaneous conflict-free editing, a teammate cursor gliding across your screen. Building real-time collaboration means choosing between OT and CRDTs, separating presence from persistence, and sizing the transport. The architecture below covers the decisions behind any serious collaborative editor.

Why does the naive approach fail?

Last-write-wins drops keystrokes when two people edit the same paragraph; the latest write overwrites whole characters without warning. Document locking with one person at a time feels like a 1998 interface and defeats the purpose of a shared editor.

OT or CRDT: which model wins?

Operational Transformation transforms concurrent operations against server ordering; the design is complex and server-authoritative, with ShareDB as the classic implementation. CRDTs guarantee mathematical convergence without central coordination, and Yjs plus Automerge lead the mature implementations. Both solve the same problem with opposite trade-offs: OT concentrates intelligence on the server, CRDT distributes state across clients.

How does Yjs work in practice?

The document becomes shared types (Y.Text, Y.Map) manipulated like local structures. The provider layer abstracts the network: y-websockets for a dedicated server, y-webrtc for P2P. Offline edits accumulate on the client and merge on reconnect. The awareness API drives cursors, selections, and displayed names.

How does a presence indicator work?

Presence is ephemeral state: cursor position, active selection, typing status. This state lives outside CRDT persistence and dies with the session. A heartbeat every 15 seconds, paired with faster expiry, keeps the participant roster honest when someone closes the tab without saying goodbye.

Do WebSockets handle the transport?

They do, and binary encoding keeps bandwidth sane: Yjs updates stay under 100 bytes per keystroke batch. Broadcast rooms take scope by document ID, so the relay forwards updates just to whoever opened that document.

Which server architecture scales?

A stateless relay serves the start of the project. Without snapshotting, memory grows without limit; compact the document every N updates to contain size. Redis pub/sub fans out across relay instances, and sticky sessions by document ID prevent connection hops mid-edit.

How do you persist collaborative documents?

Debounced snapshots every 5 seconds go to object storage (S3, GCS) and capture current state. The update log stays retained for audit and recovery; restoring means replaying the log onto the last snapshot. The debounce balances write cost against loss risk.

How do you test simultaneous editing?

Deterministic simulation of delayed and reordered messages exposes convergence bugs unit tests never find. Property tests with two virtual clients and a fixed seed reproduce the scenario in CI as many times as you need.