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.
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.
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.
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.
- 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.
- 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.
- 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.
- 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).