Skip to main content

Real architecture · Senior

Figma: how multiplayer works

Real production architecture. Key points: collaborative editing.

17 min read · Source: Figma · Content reviewed on October 23, 2026

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.

  1. When opening the document, the client starts by downloading a copy of the file.

    Architecture diagram: Figma: clients, per-document process, and separate data
    CLClient (web page)downloads a copy
    CLOther client
    CPDocument process
    CPSync for other data
    DBPostgres
  2. From then on, updates in both directions are synchronized over the WebSocket connection with the document's process.

    Architecture diagram: Figma: clients, per-document process, and separate data
    CLClient (web page)
    CLOther client
    CPDocument process
    CPSync for other data
    DBPostgres
  3. Everyone editing the same document connects to the same process.

    Architecture diagram: Figma: clients, per-document process, and separate data
    CLClient (web page)
    CLOther client
    CPDocument process
    CPSync for other data
    DBPostgres
  4. 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.

    Architecture diagram: Figma: clients, per-document process, and separate data
    CLClient (web page)reconecta
    CLOther client
    CPDocument process
    CPSync for other data
    DBPostgres
  5. Comments, users, teams and projects live in Postgres and reach clients through a completely separate system, outside multiplayer.

    Architecture diagram: Figma: clients, per-document process, and separate data
    CLClient (web page)
    CLOther client
    CPDocument process
    CPSync for other data
    DBPostgresoutside 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.

AbordagemWhat it isCost or gain for Figma
OTStandard multiplayer algorithm, popularized by apps like Google DocsGreat for long texts with little overhead, but complicated and hard to implement correctly
CRDTData structures with mathematical properties that guarantee eventual consistencyDesigned for decentralized systems, with unavoidable performance and memory overhead
FigmaOwn system, inspired by several separate CRDTs used in combinationServer 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.

  1. Two clients change unrelated properties of the same object: there is no conflict.

    Architecture diagram: Figma: conflict on the same property
    CLClient X
    CLClient Y
    CPDocument server
  2. 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.

    Architecture diagram: Figma: conflict on the same property
    CLClient X
    CLClient Y
    CPDocument serverdefines the order
  3. On the client, the change is applied immediately, without waiting for the server's confirmation, so that Figma feels as responsive as possible.

    Architecture diagram: Figma: conflict on the same property
    CLClient Xapplies instantly
    CLClient Y
    CPDocument server
  4. To avoid the flicker of confirmed old values overwriting new unconfirmed ones, the client discards server changes that conflict with its own unconfirmed ones.

    Architecture diagram: Figma: conflict on the same property
    CLClient Xdiscards the conflicting one
    CLClient Y
    CPDocument server
  5. Each person's changes go up to the server and are distributed to the others.

    Architecture diagram: Figma: conflict on the same property
    CLClient X
    CLClient Y
    CPDocument server

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.

  1. The link to the parent is a property of the child, so moving an object preserves its identity.

    Architecture diagram: Figma: concurrent reparenting
    CLClient X
    CLClient Y
    CPDocument server
  2. Without restrictions, concurrent edits can form a cycle: one client makes A a child of B while another makes B a child of A.

    Architecture diagram: Figma: concurrent reparenting
    CLClient X
    CLClient Y
    CPDocument server
  3. The server rejects parent updates that would cause a cycle, so a cycle cannot exist on it.

    Architecture diagram: Figma: concurrent reparenting
    CLClient X
    CLClient Y
    CPDocument serverrejects cycles
  4. 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.

    Architecture diagram: Figma: concurrent reparenting
    CLClient Xpending change
    CLClient Y
    CPDocument server
  5. 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.

    Architecture diagram: Figma: concurrent reparenting
    CLClient Xobjects out of the tree
    CLClient Y
    CPDocument server

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.