Real architecture · Senior
Figma: how multiplayer works
Real production architecture. Key points: collaborative editing.
Short answer
Real production architecture. Key points: collaborative editing. Figma's first save model downloaded the document, edited locally in the browser and sent the entire document back from time to time. It was a practical approach, easy to build and understand. But over time, and with more team features, a problem became clear: people sometimes saved over each other's work without realizing…
01 · CONTEXT
Before multiplayer: saving the whole document
Figma's first save model downloaded the document, edited locally in the browser and sent the entire document back from time to time. It was a practical approach, easy to build and understand. But over time, and with more team features, a problem became clear: people sometimes saved over each other's work without realizing it, and someone who received a link sometimes saw the old version because the save had not finished yet.
The team even explored cheaper alternatives, such as a baton mode in which only one editor is active at a time, but knew the optimal solution was simultaneous editing. The engine's idea is simple in theory: each person's changes go up to the server and are distributed to the others in real time; two simultaneous changes are independent unless they hit the same property of the same object, in which case the most recent one wins.
02 · ARCHITECTURE
Clients, WebSockets and one process per document
Figma clients are web pages that talk to a cluster of servers over WebSockets. At the time of the article, the servers started a separate process for each multiplayer document, and everyone editing that document connects to that process.
When opening the document, the client starts by downloading a copy of the file.
From then on, updates in both directions are synchronized over the WebSocket connection with the document's process.
Everyone editing the same document connects to the same process.
If the person was offline, on returning the client downloads a fresh copy, reapplies the edits made offline on top of the latest state and resumes synchronization over a new connection.
Comments, users, teams and projects live in Postgres and reach clients through a completely separate system, outside multiplayer.
Multiplayer only synchronizes changes to documents. According to the source, the two systems have separate implementations because of different trade-offs in performance, offline availability and security. Connecting and reconnecting are simple; all of multiplayer's complexity lies in handling updates to documents that are already connected.
03 · OT AND CRDT
Why not OT, and why only “inspired by” CRDT
Figma chose not to use operational transformation (OT), the standard multiplayer algorithm popularized by apps like Google Docs. As a startup, it valued shipping features quickly, and OTs were too complex for the problem; it therefore built its own system, simpler and easier to implement.
OTs are great for editing long texts with little memory and performance overhead, but they are very complicated and hard to implement correctly. Since Figma is not a text editor, it did not need that power.
The inspiration came from CRDTs, which satisfy mathematical properties that guarantee eventual consistency: if there are no more updates, everyone who accesses the structure ends up seeing the same thing. This constraint is about correctness, because two clients editing the same document cannot diverge forever.
Figma, however, does not use true CRDTs. They were designed for decentralized systems, with no central authority, and this brings unavoidable performance and memory overhead. Since Figma's server is the central authority, that overhead can be removed, resulting in a faster, leaner implementation. The final structure is also not a single CRDT: it combines several.
| Abordagem | What it is | Cost or gain for Figma |
|---|---|---|
| OT | Standard multiplayer algorithm, popularized by apps like Google Docs | Great for long texts with little overhead, but complicated and hard to implement correctly |
| CRDT | Data structures with mathematical properties that guarantee eventual consistency | Designed for decentralized systems, with unavoidable performance and memory overhead |
| Figma | Own system, inspired by several separate CRDTs used in combination | Server as central authority removes the overhead: faster, leaner implementation |
04 · CONFLICTS
The document as a map of properties
Every Figma document is a tree of objects, similar to the HTML DOM: a root, pages beneath it and a hierarchy of objects on each page. Each object has an ID and a collection of properties with values, which can be seen as a two-level map. For that reason, adding features to Figma usually means just adding properties to objects.
The server stores the last value any client sent for each property of each object. Changing unrelated properties of the same object, or the same property on unrelated objects, does not generate a conflict. A conflict occurs when two clients change the same property of the same object, and the document keeps the last value sent to the server. It is similar to the last-writer-wins register from the CRDT literature, without a timestamp, because the server defines the order of events.
Two clients change unrelated properties of the same object: there is no conflict.
If both change the same property of the same object, the document keeps the last value sent to the server, which defines the order of events.
On the client, the change is applied immediately, without waiting for the server's confirmation, so that Figma feels as responsive as possible.
To avoid the flicker of confirmed old values overwriting new unconfirmed ones, the client discards server changes that conflict with its own unconfirmed ones.
Each person's changes go up to the server and are distributed to the others.
One consequence is that changes are atomic at the boundary of the property value: the final value is always a value sent by some client. That is why simultaneous editing of the same text does not work in Figma: if the text is B and someone changes it to AB while another person changes it to BC, the result will be AB or BC, never ABC. Figma accepts this because it is a design tool, not a text editor.
05 · OBJECTS AND TREE
Creating, deleting and reparenting without losing identity
Creating and deleting objects are explicit protocol actions: writing a property on a nonexistent ID does not create the object. Deleting erases all of the object's data from the server, including its properties. That data stays in the undo buffer of the client that deleted it, which is responsible for restoring it if the person undoes; this keeps long-lived documents from growing without bound.
The system depends on clients generating unique IDs: each client receives its own ID, included in the IDs of the objects it creates, so two clients never generate the same ID. The server cannot assign these IDs because object creation must work offline.
The most complicated part is the tree, because of reparenting, which is moving an object from one parent to another. There were two goals: changing the parent should not conflict with changes to unrelated properties of the same object, and two concurrent reparentings of the same object should never leave two copies of it in different places in the tree.
Deleting and recreating the object with a different ID would not work, because concurrent edits would be discarded when the identity changes. The solution was to store the link to the parent as a property of the child: identity is preserved, and the object does not end up with multiple parents, which could happen if each parent stored links to its children.
The link to the parent is a property of the child, so moving an object preserves its identity.
Without restrictions, concurrent edits can form a cycle: one client makes A a child of B while another makes B a child of A.
The server rejects parent updates that would cause a cycle, so a cycle cannot exist on it.
On the client it can still occur: it sent an unconfirmed change putting A under B and received from the server one that puts B under A, and it cannot reject what comes from the server.
The client parents the objects to each other and takes them out of the tree until the server rejects its change and the object returns to the right place.
To order the children of a parent, Figma uses fractional indexing: the object's position among the children is a fraction between zero and one (exclusive), and the order comes from sorting the children by that position. Inserting an object between two others means giving it the average of its neighbors' positions. The link to the parent and the position are stored as a single property, so they update atomically.
06 · UNDO AND LESSONS
Undo, performance and what the team learned
Undo has a natural definition in single-person mode, but in multiplayer it is confusing by nature. The principle that guided the team: if a person undoes a lot, copies something and redoes back to the present, the document should not change. That is why, in Figma, undo modifies the redo history at the moment of the undo, and redo modifies the undo history at the moment of the redo.
The launch post reports other challenges. Properties of the same object that needed to change together required a careful merge between changes. Seemingly simple actions on one object affected others, generating unintended conflicts between people editing seemingly unrelated objects, which led to changing part of how layout works. And performance required measurement and tuning, including reworking the file format, which was not efficient for small messages.
Before touching the real code, the team built a prototype: a page that simulated three clients connected to a server and showed the entire state of the system, with scenarios of offline clients and limited-bandwidth connections. Among the post's lessons is that spending time on research and prototyping early paid off.
Frequently asked questions
What is Figma: how multiplayer works?
Real production architecture. Key points: collaborative editing.
What does the Figma: how multiplayer works design cover?
It is organized in these sections: Before multiplayer: saving the whole document, Clients, WebSockets and one process per document, Why not OT, and why only “inspired by” CRDT, The document as a map of properties, Creating, deleting and reparenting without losing identity, and Undo, performance and what the team learned.
How long is Figma: how multiplayer works and what level is it?
It takes about 17 minutes to read and is rated Senior level.
Now design it yourself
Run this case as an interview in the System Design school: you make the decisions, the tutor challenges them and you see how your design scores.