00 — Intro

Real-time collaboration is not one feature.

It's a stack of illusions. Everyone feels like they share one live document; in reality each person edits a local copy that constantly reconciles under latency, packet loss, and concurrent conflict. When Figma feels instant and Miro feels fluid, it's because every layer of that illusion has been carefully constructed.

This is a visual tour through each layer, built on hand-rolled primitives — a simulated network with tunable latency and packet loss, a minimal CRDT in fewer than 40 lines, and scripted ghost peers you can watch move in real time. No Liveblocks, no Yjs. The piece is the library.

  1. Layer 01

    Presence

    Everyone sees everyone else's cursor, in real time. The cheapest illusion and the highest-impact one.

  2. Layer 02

    Optimism

    Your edits appear instantly — no waiting for the server to confirm. Latency becomes invisible.

  3. Layer 03

    Conflict

    Two people edit the same thing at once. Without a strategy, one of them silently loses their work.

  4. Layer 04

    CRDT

    Conflict-free Replicated Data Types: a family of data structures that merge concurrent edits mathematically.

  5. Layer 05

    Awareness

    Showing who's looking at what — selection overlays, name labels, soft locks — without hard blocking.

  6. Layer 06

    Offline

    Disconnected, edits queue locally. On reconnect, the merge should be seamless — if the data structure allows it.


Module 01

Presence & live cursors

The cheapest illusion. Everyone sees everyone else's cursor, flowing in real time — even though the network delivers discrete, throttled samples.

Cursors are the first signal that you're not alone. They also reveal the first mismatch between what feels real and what's actually happening on the wire.

The cursor position you see is not the remote user's actual position. It's a stale sample, arriving at whatever rate the sender chose to broadcast — typically 10–30 times per second. Sending every pointer-move event would flood the network; not interpolating would produce visible jitter. So every collaborative tool interpolates.

Below, three ghost peers move on scripted paths. The update rate slider controls how often they broadcast their position. Toggle interpolation off and watch the cursors jump between samples instead of flowing between them.

Live cursors · 3 ghost peers
MiaLeoRin
15 Hz · interpolated
Drag the slider or toggle interpolation to feel the difference.
At 30 Hz with interpolation on, cursors feel continuous. At 5 Hz without interpolation, they teleport — which is exactly what the network is actually delivering. The smooth version is a designed fiction.

Module 02

Optimistic local updates

Apply your edit instantly in the local UI. Send it to the server in the background. Rollback on failure. Without this pattern, every interaction carries the full round-trip latency.

On a 200ms connection, a pessimistic editor feels broken. Every drag, every keystroke, every color change waits for server acknowledgement before updating the UI. Users report that the product is "slow" even when the network is fine.

Optimistic updates invert the order: apply locally first, sync in the background. If the server rejects the change (e.g. a conflict or permissions error), roll back. In practice, rollbacks are rare enough that the optimistic path covers almost all sessions.

Drag the cards below. Toggle between optimistic and pessimistic, and use the latency slider to feel what a cross-continent round-trip does to a pessimistic editor.

Optimistic vs pessimistic · drag the cards
Design brief
User research
Prototype
pessimistic · 400ms round-trip
With optimism off, the card waits for the simulated server response before moving.
Figma, Linear, and Notion all apply optimistic updates. The visible undo that snaps back after a conflict is the rollback — rare, but it's the price of the optimism.

Module 03

The conflict problem

Two people edit the same property at the same moment. Without a merge strategy, the server must pick one — and it silently drops the other.

Concurrent edits are not a bug — they're the normal condition of a shared canvas. The question isn't whether to handle them, but how.

The simplest strategy is last-write-wins (LWW): whichever edit arrives at the server most recently overwrites the previous value. It's easy to implement and works well for properties where any valid value is acceptable — like a cursor position. But for properties that represent meaningful user intent — the color of an object, the content of a text field — LWW silently discards one person's work.

The demo below simulates two peers editing the same object's color simultaneously. Both see their change applied locally (optimistic update). When both reach the server, LWW picks the later arrival. The earlier one is gone.

Concurrent edits · LWW strategy
shared object
Edit log

No edits yet.

Both peers apply locally. Only one survives the merge.
LWW is fine for ephemeral state like cursor positions where being slightly wrong is harmless. For anything a user deliberately created — text, shapes, properties — silent data loss is unacceptable. That's why CRDTs exist.

Module 04

Resolving it: CRDT

A Conflict-free Replicated Data Type resolves concurrent edits mathematically — no server arbitration required. Both peers' edits survive; the merge is deterministic.

A CRDT is a data structure with one key property: any two replicas can be merged in any order and always arrive at the same result. The merge function is the thing you'd normally write a server for — except it runs locally, in every client, without coordination.

For object properties — color, size, label — the simplest CRDT is the LWW (Last-Write-Wins) register. Each write is tagged with a timestamp and a peer ID. On merge, the higher timestamp wins. This is essentially the same as "whoever edited last wins" — but now both clients compute the same winner locally, without asking the server.

The demo below lets you and a simulated peer ("Mia") each choose a color independently. Your timestamp is always 100ms ahead of hers — so yours wins on merge. Change the order mentally: if Mia had edited later, her color would survive.

LWW CRDT merge · both edits survive to merge step
You
Merged
Mia (ghost peer)

Mia's timestamp is always 100ms behind yours — so your color wins on merge. The algorithm doesn't need a server to decide.

Neither edit is silently discarded — the merge function picks the winner deterministically.
For text editing, Figma uses fractional indexing to order layers without renumbering — another CRDT shape. Google Docs uses Operational Transformation (OT) instead: edits carry intent rather than timestamps, and must be transformed against concurrent edits before applying. Both solve the same problem with different trade-offs.

Module 05

Awareness & soft locks

Show who's working on what — selection overlays, name labels, presence rings — without blocking anyone. Hard locks create deadlocks. Soft locks communicate intent.

Awareness is the layer between presence (knowing someone is here) and coordination (knowing what they're doing). In Figma, when a teammate selects a component, you see their colored selection ring and name label. You can still edit the same element — they don't hold a lock — but you have enough context to coordinate.

Hard locks — "this layer is checked out by Mia, you cannot edit it" — solve the conflict problem but create a worse one: blocked workflows, forgotten checkouts, and contention. Most mature collaborative tools abandoned hard locks in favour of soft awareness signals.

The canvas below shows two ghost peers with live selection states. Toggle soft-lock mode to see the difference between awareness-only and a visual that communicates intent more strongly.

Awareness canvas · 2 ghost peers
MiaFrame 1
Component
LeoText layer
Click an object to 'select' it. Ghost peers show their selections with colored borders.
Figma's approach: colored selection borders with peer names. No blocking. Notion: last writer wins, no visible awareness of concurrent editing. Google Docs: paragraph-level awareness, caret positions synced per user. Different products tune awareness granularity to their editing model.

Module 06

Offline & reconnect

When the connection drops, edits queue locally. On reconnect, the queue flushes and merges with any server changes. If your data structure supports it, this is nearly free.

Offline support is not a separate feature — it's a consequence of already doing optimistic updates and using a merge-safe data structure. If your local state is the source of truth for the UI and your sync protocol supports out-of-order delivery, offline just means the queue drains to zero instead of immediately.

Figma's "you are offline" banner is the most honest handling: local changes apply visually, the queue is preserved, and on reconnect the merge happens silently. The user loses nothing unless there was a hard conflict they needed to resolve.

Toggle offline, make a few edits, then reconnect. The queued edits flush into the synced state using the same LWW merge from Module 04.

Offline queue · goes-offline-and-comes-back
Local (your view)

No edits yet.

Server (synced)

Nothing synced yet.

Server state stays frozen while offline. Local state updates. Reconnect merges them.
Local-first software takes this further: the local state is the authoritative source, and cloud sync is optional. Linear's model is close to this — interactions feel instant even on a slow connection because the local state is never waiting for network acknowledgement.

07 — In the wild

Who does what well.

Once you see the layers, you notice them everywhere. Every collaborative tool has made explicit choices on presence granularity, conflict strategy, and offline behaviour. Most of those choices are invisible when they work — which is the goal.

Best in class

Figma

Fractional indexing for layer ordering, so concurrent reorders never conflict. Cursor positions synced at ~60Hz with interpolation. Selection state and presence managed separately from the document CRDT — a clean separation of concerns. The multiplayer architecture is documented in their engineering blog.

Six things that hold.
  1. 01Presence is throttled + interpolated — the smooth cursor is a designed fiction.
  2. 02Optimistic updates hide latency; rollbacks are the cost, and they're rare.
  3. 03LWW is fine for ephemeral state; it's silent data loss for intentional edits.
  4. 04CRDTs make concurrent merges deterministic without server arbitration.
  5. 05Soft awareness beats hard locks — communicate intent, don't create deadlocks.
  6. 06Offline is nearly free if your data structure already handles out-of-order merges.

By Sid Bhattacharjee · Part of a series on foundational software concepts