ML Systems Review

CRDTs in Production: Lessons from Figma's Multiplayer Engine

Figma's multiplayer is often cited as the canonical consumer CRDT system. Reading their published engineering posts closely, it is better described as a server-authoritative, last-writer-wins data model that borrows ideas from CRDT theory. That distinction matters if you are building something similar.

Distributed Systems
By Priya Ramachandran , MS Reviewed by Dr. Nadia Volkov , PhD
11 min read
TL;DR

Figma's multiplayer engine is frequently described as "CRDT-based", but a careful reading of Evan Wallace and Rasmus Andersson's engineering blog posts from 2019 to 2022 suggests it is actually a server-authoritative last-writer-wins system with CRDT-style properties per field. The server assigns a global ordering; clients send optimistic operations and reconcile when the server's decision differs. This trade-off — give up peer-to-peer convergence to keep the data model simple — is a practical lesson for any team building a collaborative editor in 2023.

Updated 2026: Looking back from today, the Figma-style server-authoritative pattern has become the dominant architecture for new collaborative editors (Linear, Notion's 2024 rewrite, and most of the AI-document-editing startups). True peer-to-peer CRDT systems — Yjs, Automerge — have found a home in local-first tooling but remain a minority in consumer web applications.

Figma is frequently cited, in conference talks and architecture threads, as "the CRDT one". The shorthand is convenient and wrong. Figma's multiplayer engine borrows ideas from the Conflict-free Replicated Data Types literature — specifically from Shapiro, Preguiça, Baquero and Zawirski's 2011 paper and from the later work on operational transform alternatives — but it is not a CRDT in the strict, peer-to-peer-convergence sense that the research community means. Understanding what it actually is matters if you are an engineer in 2023 trying to decide whether to build your own collaborative system.

This article is a reading of Figma's public engineering material, principally Evan Wallace's 2019 post How Figma's multiplayer technology works and subsequent follow-ups through 2022, interpreted through the lens of the broader distributed-systems literature. We did not talk to anyone at Figma. Everything here is based on their published writing and on what the system demonstrably does from the outside.

What a CRDT actually is

A CRDT is a data type whose replicas can be updated independently and merged deterministically, without coordination, such that all replicas converge to the same state once they have seen the same set of updates. The theoretical guarantee is strong: no central server, no consensus, no locking. Two people in two offline laptops can edit the same document and, when they sync, their changes merge without conflict.

The mathematical scaffolding is non-trivial. For a data structure to be a CRDT, its operations must form a commutative, associative, and idempotent semilattice, or equivalently, its state transitions must be ordered by a lattice structure where the join operation is well-defined. In practice this means CRDTs come in two flavours:

  • State-based (CvRDT). Each replica periodically broadcasts its full state; merge is a lattice join. Simple to reason about, expensive to sync.
  • Operation-based (CmRDT). Each replica broadcasts operations; the delivery layer is required to deliver every operation exactly once in causal order. Cheap bandwidth, complex delivery semantics.

Real-world CRDT implementations — Yjs, Automerge, Riak's data types — add substantial engineering on top of this to handle text editing, rich lists, garbage collection of tombstones, and the realities of network failure. The open problem, and the reason peer-to-peer CRDTs have not swept consumer software, is that fully general CRDT text editing produces documents whose size grows unboundedly with edit history unless you add a garbage-collection protocol, which reintroduces coordination.

What Figma actually does

From Wallace's 2019 post and subsequent writing, the Figma architecture as of 2023 has four ingredients worth naming.

A server-authoritative document model

There is a server. The server holds the canonical state of the document. Clients do not merge with each other; they merge with the server. This is a fundamental departure from a textbook CRDT: in the CRDT literature, every replica is symmetric. In Figma's system, one replica — the server — is privileged. It gets to decide the final ordering of operations.

This is a pragmatic choice. The server gives you a natural place to do authorisation, to garbage-collect old operations, to snapshot for disaster recovery, and to enforce schema validation. All of which are hard or impossible in a pure peer-to-peer CRDT.

Per-property last-writer-wins with vector-clock-like versioning

The document is a tree of objects. Each object has properties. Each property is assigned a version number. When two clients update the same property concurrently, the server sees both updates, picks a winner (the one with the higher server-assigned timestamp), and broadcasts the winner back to every connected client. The losing client silently discards its local state for that property and adopts the server's version.

This is last-writer-wins (LWW), which is a CRDT primitive but a weak one: it is not conflict-free in the informal sense — one user's change simply loses. From a mathematical standpoint the semilattice join is well-defined (max of timestamps), so the formal CRDT property holds. From a UX standpoint, the user whose change was discarded might well be surprised. Figma's design-tool domain mitigates this: in practice, two users rarely edit the exact same property of the exact same layer at the exact same instant.

Tree restructure via an explicit parent pointer

Where Figma's approach becomes subtle is in the handling of tree moves. If two users simultaneously re-parent the same layer, a naive LWW on a "parent" property can produce cycles. Wallace's 2019 post describes the mitigation: the server validates the resulting tree after every operation and, if a cycle would be created, one of the re-parent operations is rejected and rolled back on the client. This is not a CRDT operation — CRDTs do not "roll back" — it is an imperative server-side conflict resolver.

Optimistic local edits with server reconciliation

Clients apply their own edits immediately to the local state and send them to the server asynchronously. The server processes operations in the order they arrive, assigns each a canonical version, and broadcasts them to all connected clients. Clients then reconcile: if the server's version of a property differs from the client's local version, the client replaces its local state with the server's.

The reconciliation step is what makes this feel like a CRDT to a user: changes from other people arrive and blend in. But underneath, there is a single source of truth and a single arbitrating actor. Take the server away and the system stops working.

Why Figma did not use classical operational transform

The alternative to a CRDT-flavoured approach is Operational Transform (OT), the family of algorithms that powered Google Docs, Etherpad, and the older generation of collaborative editors. OT works by transforming concurrent operations against each other so that they have the same effect regardless of the order in which they arrive.

OT has a reputation, not undeserved, for being difficult to get right. The transformation functions for even moderately rich data types (a tree of nested objects with arbitrary properties) are notoriously hard to prove correct. Google Wave's OT implementation famously required multiple iterations before it converged reliably. For a design tool with a complex scene graph — rectangles, groups, boolean operations, masks, constraints — the OT approach would have produced a combinatorial explosion of transformation functions.

Figma's approach sidesteps OT entirely by using the server as a linearisation point. Operations do not need to be transformed against each other because they are applied in a single global order. This is cheaper to implement and easier to reason about, at the cost of requiring a server and giving up offline editing beyond a reconnection window.

Figure 1. Three approaches to collaborative editing, compared.
                              Classical OT       Pure CRDT       Figma-style
                              (Google Docs)      (Yjs)           (server-auth LWW)
  -----------------------     -------------      -----------     -----------------
  Requires a server?          Usually yes         No              Yes
  Works offline?              Limited             Fully           Limited (buffer)
  P2P convergence?            No                  Yes             No
  Garbage collection hard?    No                  Yes             No
  Transformation complexity   High                Medium          Low
  Typical doc-size overhead   <5%                 20–200%         <5%
  Auth/validation point       Server              Application     Server
  Tree-move cycle safety      Transform manual    Needs protocol  Server validates

A sketch of the wire protocol

Figma has not published the wire protocol, but from the traffic patterns visible in the browser DevTools network panel it is clearly a small number of operation types over a persistent WebSocket. The pattern looks like this pseudo-code, which we emphasise is a reconstruction for teaching purposes and not Figma's actual code:

// Conceptual — not Figma's actual protocol.

// Sent by client when the user edits a property.
type SetProperty = {
  op: "set_property";
  objectId: string;            // UUID of the node
  property: string;            // e.g. "fills[0].color.r"
  clientVersion: number;       // client's local monotonic counter
  value: any;                  // new value
};

// Broadcast by server after applying and ordering.
type PropertyChanged = {
  op: "property_changed";
  objectId: string;
  property: string;
  serverVersion: number;       // server's authoritative version
  value: any;
  originClientId: string;      // to let the sender suppress echo
};

// Special path for tree structural changes.
type ReparentNode = {
  op: "reparent";
  objectId: string;
  newParentId: string;
  beforeSiblingId: string | null;
  clientVersion: number;
};

// Server may reject if the resulting tree would contain a cycle.
type ReparentRejected = {
  op: "reparent_rejected";
  objectId: string;
  reason: "would_create_cycle" | "permission_denied";
  serverStateVersion: number;
};

A client, having sent SetProperty, applies the change locally and waits for the corresponding PropertyChanged echo. If the echo's serverVersion is higher than any version the client has for that property, it is accepted; otherwise the server's state is kept and the client's local buffered operation for that property is discarded.

What this architecture gives up

The main cost of Figma's approach is that offline editing is fundamentally limited. A client that loses connectivity can continue to edit its local state; when it reconnects, its changes are sent to the server and reconciled against whatever happened while it was offline. If another user was editing the same document online during that interval, the offline user's changes may be silently overwritten on a per-property basis.

Figma's in-product behaviour matches this: there is no rich offline mode. You can keep editing for a short window after connection loss (the app buffers your operations), but the product is clearly designed for the always-online case. This is a reasonable product choice for a design tool used in office environments; it would not be a reasonable choice for a field tool or a note-taking application.

The secondary cost is that the server becomes a scaling bottleneck. Every operation must reach a central process that owns that document's state. Figma's published material suggests each document is pinned to a single server process, with horizontal scale achieved by sharding at the document level. For a design tool this is acceptable: documents are bounded in size and in concurrent users. For a global multi-user document (think a shared Google Doc with 500 concurrent editors) the single-owner pattern would be a more serious constraint.

Lessons for collaborative-system designers

If you are building a collaborative editor in 2023 and you are considering the CRDT-versus-OT-versus-server-authoritative question, the useful lessons from the Figma architecture are these.

  1. Question whether you actually need peer-to-peer convergence. If your product is always-online and you control a server, the CRDT property is academic. A server-authoritative LWW model is dramatically simpler, and the formal CRDT property can be preserved at the per-property level without adopting the full machinery.
  2. Tree moves are the edge case. Almost all of the genuinely hard cases in collaborative editing — the ones that require real conflict resolution rather than LWW — are structural tree operations. Putting tree restructure on a separate protocol path with server-side validation is worth the extra complexity.
  3. Vector clocks are rarely worth it. For per-property LWW, a single server-assigned monotonic version is sufficient and is much easier to store and reason about than a vector clock per property per client.
  4. Do not conflate the network layer and the data model. The Figma system separates "how operations get to the server" (WebSocket protocol, buffering, reconnection) from "what the server does with them" (global ordering, validation, broadcast). Most collaborative-system bugs we have seen live at the seam between these two concerns.

Where pure CRDTs still win

None of this is an argument against CRDTs. There are domains where the peer-to-peer convergence guarantee is not optional. Local-first software (in Martin Kleppmann and Ink & Switch's sense), collaborative tools designed to work across unreliable networks, and systems that must survive the indefinite unavailability of any central coordinator all benefit from pure CRDT primitives.

The Yjs project, in particular, has shown in the last three years that a carefully engineered CRDT library can approach the performance and bandwidth overhead of a server-authoritative design for certain workloads. If you are building a local-first editor or a peer-to-peer collaboration tool, Yjs and Automerge are both serious production options in 2023 in ways that they were not in 2019.

The Figma system is simply not that kind of system. It is a hosted service whose core value proposition depends on a server. Calling it "CRDT-based" undersells how much of the engineering went into the server-side orchestration and how little of the peer-to-peer theory it actually needs. The accurate description is: a server-authoritative document store with CRDT-inspired per-property semantics and an optimistic client protocol. That is a mouthful, but it is what the system is.

Closing note

The interesting question, looking forward from late 2023, is whether any new collaborative editors will choose a true peer-to-peer CRDT foundation over a Figma-style server-authoritative one. Our guess — and it is a guess — is that for hosted, always-online consumer products, the Figma pattern will continue to dominate because it is so much easier to operate. The CRDT renaissance, if there is one, will happen in local-first tools and in the quieter corners of enterprise software where disconnected operation is a first-class requirement.

Reviewed for technical accuracy by Dr. Nadia Volkov. Sources: Wallace, How Figma's multiplayer technology works (2019); Shapiro et al., Conflict-free Replicated Data Types (INRIA, 2011); Kleppmann, A Critique of the CAP Theorem (2015).