Collaboration
Whiteboard sync - the cursors cost more than the drawing
Why a shared canvas is mostly a broadcast problem, and what happens to a shape that two people grab at once.
What this board gets wrong on purpose
The tension
A drag emits twenty-five absolute-position ops a second, and last-writer-wins resolves each of them by arrival order - so two people dragging one shape produce a tug of war at 25 Hz that ends wherever the network left it, not where either person meant. The board softens that with a drag claim broadcast on the PRESENCE channel, which is exactly the channel that is unacknowledged, unordered and allowed to drop frames: two people who grab the same shape inside one 60 ms presence window both believe they hold it, and the claim is advisory anyway because a server that enforced it would have to keep per-shape lock state and decide what happens when the holder’s laptop closes. The honest fix is intent-carrying ops - "move by this delta", or a claim on the ordered channel with a server-side lease - and both cost a round trip on the one interaction that has to feel like direct manipulation. Underneath all of it the room is one process holding the board in memory with a 250 ms debounce to storage, so a deploy disconnects everyone and an unclean kill loses the last quarter second of every board on the machine.
Requirements
Ask these before drawing anything
- How many people may be on one board? Six is a design; forty is a different design; four hundred is a broadcast product with a canvas attached, and presence has to become one aggregated frame rather than n of them.
- Is a drag an intent or a position? "Move to (x, y)" is trivial to implement and loses an argument between two draggers. "Move by (dx, dy)" keeps both intents and drifts. There is no third option that is both.
- May a shape be locked while somebody is manipulating it? A real lock needs a lease, a holder, and a rule for what happens when the holder’s laptop closes mid-drag. An advisory claim needs none of that and does not actually prevent anything.
- Does the board need to be correct while nobody is looking at it? If yes, the in-memory room is a cache with a write-behind and needs a durability story. If no - and for a whiteboard it largely is no - the debounce can be generous.
- How large may one board get? Canvases grow without bound because nothing is ever deleted, only moved off to the side. The p99 board is two orders of magnitude bigger than the median.
- Must a late joiner see the board instantly? Sending the whole document is simple and is megabytes; sending a viewport-shaped subset is fast and means the client no longer holds a complete document, which breaks undo.
- Is there an audit requirement - who moved this? That turns the op log from an optimisation into a retained record with its own lifetime.
- What is the acceptable behaviour on reconnect after two minutes? Replay, or reload? Replay needs op retention; reload loses local unsent work.
Functional
- Several people draw, move and edit shapes on one canvas and converge on the same board.
- Every participant sees the others’ cursors, and their viewport rectangles when they are following somebody.
- A drag is smooth locally at 60 fps regardless of network conditions.
- A late joiner receives the current board and then follows along from that revision.
- Undo is per person: undoing your own last action must not undo somebody else’s.
- A board survives everybody leaving and is identical when reopened.
Non-functional
- Local feedback: within one frame, 16 ms. A canvas that waits for a server to move a shape is unusable in a way a text editor is not - the pointer is already somewhere else.
- Remote application: p50 under 150 ms, p99 under 500 ms in region. Above about 250 ms a remote cursor stops looking alive and starts looking broken.
- Presence has no delivery guarantee whatsoever. Dropping frames under load is correct behaviour, not degradation.
- 99.9% for opening and editing a board. Presence has no availability target.
- Convergence is a correctness property: given the same ops, every client renders the same board. Position disagreement between two clients is a bug at any latency.
Out of scope
- Real-time audio and video, which share the room concept and nothing else.
- Vector export and printing, which read a snapshot rather than the live room.
- Infinite-canvas spatial indexing for search, which is a separate board.
The rest of this board
Available on Tier Slate
This page publishes the question. The answer — 5 more written pages, a 9-step narrated walkthrough and a 5-table schema — is the board itself, and it opens in Tierslate.
- 5written pages
- 9walkthrough steps
- 5tables38 columns
5 pages behind this one
- Capacity estimation
- Storage estimation
- Availability
- How it works
- Deployment plan
More boards
Several people editing one thing without losing an edit.