1. The Headline
60fps WebGL rendering with real-time multiplayer.
Figma disrupted an industry dominated by heavy desktop apps (Sketch, Adobe Illustrator) by moving professional vector editing to the browser. But doing this natively in the browser's DOM was impossible. They had to bypass the browser's layout engine entirely and build their own rendering engine using WebGL and WebAssembly, while simultaneously solving the complex computer science problem of real-time multiplayer conflict resolution.
2. Requirements and Constraints
Functional Requirements:
- Infinite canvas vector editing.
- Real-time multiplayer (Google Docs style) where users see each other's cursors and edits.
- Support for documents with hundreds of thousands of layers.
Non-Functional Requirements:
- Performance: Must render at 60fps to feel like a native desktop app.
- Consistency: If Alice and Bob edit the same vector point at the exact same millisecond, the document state must eventually converge to the exact same result for both users.
The Ultimate Constraint: Network latency. If the client has to wait for a server round-trip to confirm that a rectangle was moved, the app will feel sluggish and unusable. Edits must be applied locally instantly, but synchronized globally without breaking the document.
3. The Naive Design & Where It Breaks
A naive approach to a multiplayer canvas:
- Store the document state as a large JSON object in a MongoDB database.
- When Alice moves a rectangle, the client sends a
PATCHrequest to the server:{ id: "rect1", x: 100 }. - The server updates the database and broadcasts the new state via WebSockets to Bob.
Where this breaks under Figma's requirements:
- The Conflict Problem: If Alice moves
rect1tox=100and Bob simultaneously movesrect1tox=200, whose edit wins? If the server just blindly accepts the last one to arrive over the network, Alice and Bob's screens will show different things until the server forces a hard sync, causing elements to violently snap across the screen. - The DOM Bottleneck: Rendering 100,000 layers as HTML
<svg>nodes will freeze the browser. The DOM is too slow for complex vector graphics. - Payload Size: Broadcasting the entire document state on every mouse movement would consume gigabytes of bandwidth per minute.
4. The Real Architecture: Layer by Layer
Normal operation: The client streams video from the CDN and maintains a persistent WebSocket/MQTT connection for real-time scores.
The Frontend Engine (WASM + WebGL)
Figma completely bypasses the DOM.
- The core editing engine is written in C++ and compiled to WebAssembly (WASM).
- The UI is rendered onto an HTML
<canvas>using WebGL. This allows Figma to leverage the user's GPU directly, achieving 60fps even with massive documents. - The React UI (panels, menus) floats on top of the WebGL canvas.
The Multiplayer Server (Ruby/Go)
Figma uses a relatively simple server architecture.
- Clients maintain a persistent WebSocket connection to a stateful multiplayer server.
- The server does not understand the complex geometry of Figma files. It is essentially a dumb pipe that receives tiny fractional edits (mutations) and broadcasts them to all other connected clients.
The Conflict Resolution Engine (Fractional Indexing)
Figma uses a custom implementation related to CRDTs (Conflict-free Replicated Data Types) to solve the multiplayer problem. Instead of locking the document (which blocks users) or using standard Operational Transformation (which requires a heavy, intelligent server), Figma relies on deterministic local execution.
When Alice changes a property, her client generates a precise mutation event. If two users change the same property simultaneously, the client uses a deterministic tie-breaker (like a timestamp and client ID) to ensure both screens eventually settle on the exact same state without server intervention.
To handle the order of layers in the sidebar, Figma uses Fractional Indexing. If Layer A is at position 1 and Layer B is at position 2, a new layer inserted between them is given position 1.5. This prevents race conditions where Alice and Bob both try to insert a layer at index 1.
5. The Hard Problem
Deterministic execution across different environments.
For Figma's sync model to work, the C++/WASM engine running on Alice's Mac and Bob's Windows machine must produce the exact same pixels when given the same sequence of mutations. Floating-point math handles rounding slightly differently on different CPUs, which can cause vector paths to diverge. Figma had to build a fully deterministic math library to ensure 100% consistency.
6. What This Means for the Client (Frontend)
Figma is the ultimate "Thick Client" architecture. The frontend does 99% of the work.
Optimistic Application
When you drag a shape in Figma, the client does not ask the server for permission. It applies the mutation locally to the WASM memory state and renders it to WebGL instantly (Optimistic UI).
Syncing and Re-parenting
Simultaneously, the client queues the mutation and sends it over the WebSocket. If the server responds with an incoming mutation from Bob that conflicts with Alice's local state, the WASM engine rapidly rolls back Alice's local changes, applies Bob's confirmed changes, and re-applies Alice's changes on top. Because this happens in WASM, it occurs in less than a millisecond, making it invisible to the user.
7. Failure Modes & Graceful Degradation
- Offline Mode: If the WebSocket drops, the client continues to function perfectly. It queues all mutations in an internal buffer (and stores them in IndexedDB). The user can keep designing.
- Reconnection: When the connection returns, the client flushes its queue to the server. Because the system is designed to handle out-of-order mutations, the server merges the offline edits seamlessly into the live document.
8. Numbers & Tradeoffs
- Architecture: C++ compiled to WebAssembly, rendered via WebGL.
- Tradeoff: By bypassing the DOM, Figma sacrificed native browser accessibility (screen readers, text selection). They had to painstakingly rebuild native behaviors (like text wrapping, spellcheck, and input focus) from scratch inside WebGL.
9. How to Use This in an Interview
If an interviewer asks you to design a collaborative application like Google Docs, Trello, or a whiteboard:
"For real-time collaboration, we cannot rely on a REST API. We need a persistent WebSocket connection to broadcast mutations. To resolve conflicts when two users edit the same object, we should implement a CRDT (Conflict-free Replicated Data Type) or a deterministic tie-breaker on the client, rather than relying on the server to lock the document."
"To handle ordering in a multiplayer list (like dragging layers or tasks), we can use Fractional Indexing instead of integer arrays to prevent race conditions during insertion."
10. Sources
- How Figma’s multiplayer technology works
https://www.figma.com/blog/how-figmas-multiplayer-technology-works/ - WebAssembly at Figma
https://www.figma.com/blog/webassembly-cut-figmas-load-time-by-3x/