operational-transformation

3 posts

figma

How Figma’s multiplayer technology works | Figma Blog (opens in new tab)

Figma built a custom multiplayer system because traditional operational transformation (OT) was too complex for its document-editing needs. Its client/server architecture synchronizes document changes over WebSockets, supports offline editing, and separates document collaboration from other data such as comments and users. The system began as a prototype that enabled rapid experimentation before being integrated into production. ## Why Figma Built Its Own Multiplayer System - In 2015, no major design tool offered real-time collaborative editing. - Figma avoided OT, the algorithm used by tools such as Google Docs, because it considered OT unnecessarily complex for its problem space. - The custom approach was designed to be simpler and faster to implement. - Multiplayer eliminated the need to export, email, or manually synchronize design files. - It also allowed non-designers—such as copywriters and developers—to participate or view work without interrupting the designer. ## Figma’s Client/Server Architecture - Figma clients are web pages connected to a server cluster through WebSockets. - Each multiplayer document runs in a separate server process, with all editors connected to that process. - When a document opens, the client downloads an initial copy of the file. - Subsequent changes are synchronized in both directions over the WebSocket connection. - Server performance and scaling were important considerations, later addressed in part through the use of Rust. ## Offline Editing and Reconnection - Clients can continue editing while offline for an arbitrary period. - When reconnecting, the client: - Downloads a fresh version of the document. - Reapplies its locally stored offline edits to that latest state. - Resumes synchronization through a new WebSocket connection. - This keeps connection and reconnection logic relatively simple by concentrating multiplayer complexity on already-connected clients. ## Separate Systems for Different Data - Figma’s multiplayer system is used only for syncing document changes. - Comments, users, teams, projects, and similar information are stored in Postgres. - That data is synchronized through a separate system because it has different requirements involving: - Performance - Offline availability - Security ## Prototyping Before Production - Figma first created a standalone browser-based prototype rather than experimenting directly in the production codebase. - The prototype simulated three clients connected to a server and visualized the complete system state. - Engineers could test: - Offline clients - Bandwidth-limited connections - Different collaborative algorithms - Alternative data structures - Once the design was validated, the ideas were transferred into the main codebase. Figma’s experience demonstrates that collaborative systems do not always require the most established algorithm. A focused, custom protocol—validated through fast prototyping—can provide a simpler solution when its data model and product requirements differ from tools like document editors.

figma

Realtime Editing of Ordered Sequences | Figma Blog (opens in new tab)

Figma needed a way for multiple users to edit ordered object sequences simultaneously while ensuring every client eventually reached the same state. Although Operational Transformation (OT) could solve the problem, Figma chose fractional indexing because it is simpler, supports efficient reordering, and was sufficient for design documents. The trade-offs—such as possible interleaving and growing index lengths—were acceptable in Figma’s use case. ## The Realtime Ordering Problem - Figma documents contain ordered children inside groups, components, and other compound objects. - Users can insert, delete, or reorder objects while edits are applied locally and propagated asynchronously. - Because clients may receive operations in different orders, the system must guarantee eventual consistency: every client must end up with the same document. ## Operational Transformation - OT transforms concurrent operations so they preserve the intended result regardless of application order. - For example, an insertion before a deletion may require adjusting the deletion’s index so it still removes the intended characters. - OT offers: - Strong performance and low memory usage for very large sequences. - Linearized concurrent insertions rather than interleaved content. - However: - It is difficult to understand and implement correctly. - Reordering is typically represented as a delete followed by an insert. - Supporting more operation types increases implementation complexity substantially because operations must be transformed against one another. - Figma considered OT excessive because its sequences were not enormous, interleaving was acceptable, and reordering was especially common. ## Fractional Indexing - Each object receives a numeric position, and children are ordered by sorting these positions. - To insert between two objects, Figma assigns the new object the average of their positions. - Positions are arbitrary-precision fractions between 0 and 1, stored as strings to preserve precision. - Figma uses a compact base-95 representation, omitting the leading `0.` and using the full ASCII range. - Reordering requires changing only one position value. ## Trade-offs and Conflict Handling - Fractional indexes are easy to understand and implement, but: - Index strings can grow after many insertions. - Concurrent insertions may interleave. - Averaging fails if two neighboring objects have identical indexes. - Index growth is not a practical concern for Figma because document sizes and user-driven reorder operations are limited. - Interleaving is generally acceptable for design objects, which often do not overlap; users can manually correct unusual ordering. - If two clients insert between the same objects, the server assigns a unique position to prevent duplicate indexes. Figma’s experience suggests that a simpler, stable algorithm can be more valuable than a theoretically stronger one. Fractional indexing made collaborative ordering easier to maintain and extend while meeting the practical needs of a design tool.

figma

Multiplayer Editing in Figma | Figma Blog (opens in new tab)

Figma’s multiplayer editing release made real-time collaboration a core part of its design workflow. The company replaced a simple whole-document save-and-upload model after it caused overwrites, stale links, and confusing collaboration problems. Although multiplayer required major changes to conflict resolution, undo/redo, layout behavior, file formats, and performance, Figma concluded that it ultimately simplified the user experience. ## Why the Original Saving Model Failed - Early Figma downloaded documents locally, let users edit in the browser, and periodically uploaded the entire document. - This approach was easy to build and familiar to users of syncing services such as Dropbox. - In team settings, however: - Users could unknowingly overwrite one another’s work. - Shared links could display an outdated version while changes were still saving. - Version history preserved data, but did not prevent collaboration mistakes. - Alternatives such as “baton-passing,” where only one person could edit at a time, lacked the simplicity and flexibility Figma wanted. ## How Figma’s Multiplayer Engine Works - Each user’s changes are sent to the server and broadcast to other participants in real time. - Independent simultaneous changes can coexist. - When users modify the same property on the same object, Figma resolves the conflict by selecting the latest change. - Implementing this model required changing fundamental parts of the editor rather than adding multiplayer as a separate synchronization layer. ## Undo, Redo, and Conflict Resolution - Undo becomes ambiguous when other users modify the same objects afterward. - Figma adopted a guiding principle: undoing actions, copying something, and redoing back to the present should leave the document unchanged. - Redo therefore cannot simply reapply the original edits, since that might overwrite newer work by collaborators. - Conflict resolution also had to account for: - Related properties that must be changed together. - Actions that indirectly affect multiple objects. - Layout operations where apparently unrelated edits can interact. - These requirements led Figma to revise aspects of its layout system. ## Performance and File-Format Changes - Professional-quality multiplayer required extensive measurement and tuning. - Figma overhauled its file format because the previous representation was inefficient for transmitting small incremental messages. - The team expected additional challenges as new collaborative features were introduced. ## A Simpler Collaborative Experience - Multiplayer reduced UX complexity by eliminating workarounds for stale files, overwrites, and coordination. - Users can see collaborators’ mouse cursors and selections, providing immediate context about who is present and where they are working. - Cursors can also serve as lightweight communication tools, such as pointing at an object or getting someone’s attention. - Each participant appears as an avatar in the top-right corner. - Clicking an avatar lets one user present to another, making presentations opt-in rather than forcing a single presenter and synchronized viewing mode. Figma’s experience suggests that real-time collaboration is best treated as a foundational part of the editor. Despite the substantial engineering investment, multiplayer editing can make collaborative software both more powerful and easier to use.