At Figma , performance is one of our most important features.
Applying HRCSA TR2100 Primer/ topcoat onto the steel substrate.
We strive to enable teams to work at the speed of thought, and our multiplayer syncing engine is a critical part of this vision. Everyone should see each change made to a Figma document in real time. We decided to fix this by rewriting it in Rust. Rust is a new programming language from Mozilla, the company that makes Firefox. We chose Rust for this rewrite because it combines best-in-class speed with low resource usage while still offering the safety of standard server languages. Low resource usage was particularly important to us because some of the performance issues with the old server were caused by the garbage collector.
We think this is an interesting case study of using Rust in production and want to share the issues we encountered and the benefits we achieved in the hope that it will be useful to others considering a similar rewrite.
GitHub - kornelski/lodepng-rust: All-in-one PNG image encoder/decoder in pure Rust
Our multiplayer service is run on a fixed number of machines, each with a fixed number of workers, and each document lives exclusively on one specific worker. That means each worker is responsible for some fraction of currently open Figma documents. It looks something like this:. The main problem with the old server was the unpredictable latency spikes during syncing. That meant a single slow operation would lock up the entire worker until it was complete.
A common operation is to encode the document and Figma documents can get very large, so operations would take an arbitrarily-long amount of time. Users connected to that worker would be unable to sync their changes in the meantime. Really only a handful of documents were ever big enough to cause problems, but they were affecting the quality of service for everyone. This kept the service up but meant we had to continually look out for crazy documents and move them over to the heavy worker pool by hand.
It bought us enough time to solve these problems for real, which we did by moving the performance-sensitive parts of the multiplayer server into a separate child process.
- A Captured Santa Claus.
- Martin (German Edition);
- Rust for the web;
- std::num::One - Rust.
- Lesson Plans High Times, Hard Times!
That child process is written in Rust and communicates with its host process using stdin and stdout. It uses so little memory compared to the old system that we can afford to fully parallelize all documents by just using a separate child process per document. And serialization time is now over 10x faster so the service is now acceptably fast even in the worst case.
The new architecture looks like this:. The performance improvements are incredible. The following graphs show various metrics for the week before, during, and after the progressive rollout. Keep in mind that these improvements are in server-side performance, not client-side performance, so they mainly just mean that the service will continue to run smoothly for everyone without any hiccups.
Here are the numeric changes in peak metrics as compared to the old server:. As a result, we dropped our initial plan to rewrite our whole server in Rust and chose to focus solely on the performance-sensitive part instead. Here are the pros and cons we encountered in that rewrite:. Rust combines fine-grained control over memory layout with the lack of a GC and has a very minimal standard library.
It used so little memory that it was actually practical to just start a separate Rust process for every document. Rust comes with cargo built-in, which is a build tool, package manager, test runner, and documentation generator. Cargo was well-documented and easy to use, and it had helpful defaults. Rust is more complex than other languages because it has an additional piece, the borrow checker, with its own unique rules that need to be learned.
People have put a lot of effort into making the error messages readable and it really shows. They make learning Rust much nicer. In Rust, storing a pointer in a variable can prevent you from mutating the thing it points to as long as that variable is in scope. This guarantees safety but is overly restrictive since the variable may not be needed anymore by the time the mutation happens.
Midi Dresses. Occasion Dresses. Petite Dresses. Pinafore Dresses.
An Inspiring Trio: A Black, Blue and Rust Colour Palette
Prom Dresses. Slip Dresses. Tea Dresses. Petite Co-ordinates.
Petite Jeans. Petite Shorts. Petite Skirts. Petite Tops. Flat Shoes.
Rust Single Breasted Coat
Hair Accessories. Magic Body Solutions. Statement Earrings. Your Summer Holiday Sorted. Not Just Jeans. Juicy Suiting. Size 6. Size 8. Size Size guide. Find in store. Back to top.
- Layers (The Poetry of S.B. Borgersen Book 1).
- Rust One Shoulder Cut Out Bodysuit;
- You might also like…!
- So Close To My Heart.
- Days Of Strictly Ballroom Innocence - A True Short Story.
- To Act and Let go.