Curated summary
Supporting Faster File Load Times with Memory Optimizations in Rust | Figma Blog
Figma improved server-side file loading by reducing the memory overhead of its Rust data structures. Replacing per-node BTreeMaps with compact sorted vectors made deserialization faster and cut memory usage for large files by nearly 25%, despite worse theoretical operation complexity. The team also explored packing field IDs into unused pointer bits, potentially storing the same information in fewer bytes.
Smaller, Memory-Efficient Maps
- Figma files consist of nodes, each represented by properties such as type, parent, position, and dimensions.
- Nodes were stored as
BTreeMap<u16, u64 pointer>structures because ordered iteration was required for serialization. - Profiling showed these maps consumed more than 60% of a file’s memory, even though they stored metadata rather than large data payloads.
- The schema contains fewer than 200 possible fields, and nodes typically contain only a subset of them—about 60 properties on average.
- Figma replaced each
BTreeMapwith a sorted flat vector of(field ID, pointer)pairs. - Although vectors have theoretically slower insertion, lookup, and editing, their compact linear layout is more cache-friendly and faster during deserialization.
- The deployed change reduced memory usage by nearly 25% for large files and improved file-loading performance.
Saving More Memory with Bit Stuffing
- The team also investigated storing the field ID inside the pointer itself.
- While pointers are nominally 64 bits, x86 systems currently use only the lower 48 bits for memory addresses, leaving 16 bits available.
- Figma’s field IDs require exactly 16 bits, allowing a single
u64to contain both:- A 16-bit field ID
- A 48-bit memory pointer
- This representation could eliminate the separate field-ID storage and further reduce memory overhead.
- The approach had not yet been productionized because relying on unused pointer bits is architecture-dependent and could change in the future.
Figma’s results demonstrate that practical memory layout and CPU cache behavior can outweigh Big O complexity. For compact, bounded data structures, flat vectors—and carefully considered bit packing—can deliver substantial improvements in both memory efficiency and load speed.
Related reading
Continue with another curated summary.
Don’t stop early: Case-folding source code at memory speed
Read originalHow Go 1.24's Swiss Tables saved us hundreds of gigabytes | Datadog
Read originalSpeeding Up File Load Times, One Page At A Time | Figma Blog
Read originalImproving Performance with Incremental Frame Loading | Figma Blog
Read original