Why server-side workloads need sandboxing
Modern SaaS applications frequently depend on libraries that were never designed to parse hostile input. Image processing, compression, and thumbnailing are common operations, and the libraries that power them are often written in memory-unsafe languages like C++. The result is a steady history of critical memory corruption vulnerabilities. ImageTragick, a 2016 remote code execution flaw in ImageMagick, demonstrated how a single bug in a widely used processing library could compromise any service running it on user-supplied images.
Bugs are inevitable, and attempting to eliminate them all — for instance, by rewriting unsafe code in memory-safe languages — is expensive and unrealistic. Even then, no approach is foolproof. Application-level sandboxing (also called workload isolation) addresses the other side of the problem: containing the damage when a vulnerability is exploited. Sandboxing was historically expensive, immature, and difficult to operate, which led many teams to underuse it despite its value in a defense-in-depth strategy. Recent investment in the space has produced more stable and usable options, leaving teams with a wide array of primitives to choose from — but also a complex set of trade-offs to evaluate.
This is a familiar problem at Figma. On the client side, browser sandboxing technologies like WebAssembly handle untrusted input. Server-side workloads, however, often run on our own code — such as RenderServer, a stripped-down C++ version of the Figma editor — plus third-party libraries processing user-generated graphical data. Running jobs on potentially malicious input directly inside production would expose other user data, other services, and the broader infrastructure to any single compromised workload. Sandboxing limits what a breached process can access, containing an attack to the affected system.
Sandboxing primitives, from heavyweight to lightweight
Three common approaches to server-side sandboxing are virtual machines (VMs), containers, and secure computing mode (seccomp). Each operates at a different layer of the stack and offers different security and performance properties.
Virtual machines
A VM is a guest virtual computer with its own memory, disk, and CPU. Hypervisor technologies such as Firecracker, Xen, and KVM sit between the guest and the host, managing execution and providing access to host hardware resources. Figma primarily uses Firecracker as an isolation primitive through AWS Lambdas.
Containers
Container isolation happens at the operating system layer, relying on kernel features like namespaces, cgroups, and privilege dropping rather than a hypervisor. Because containers can call host syscalls directly, they tend to have lower performance overhead than VMs. Figma primarily uses nsjail, a command-line tool that combines Linux namespaces, capabilities, filesystem restrictions, cgroups, resource limits, and seccomp, where container-level isolation is appropriate.
Seccomp
A seccomp-driven approach assumes that many isolatable programs are doing pure computation and don't need dynamic access to disk or network. By restricting available syscalls via the kernel's seccomp feature, the resulting allowlist permits only the operations the program genuinely needs — ideally just allocating memory, producing output, and exiting. Figma built this directly with libseccomp into parts of its codebase.
Choosing the right fit
Because the options differ so significantly in their inner workings and security properties, selecting the right combination for a particular workload requires careful analysis of trade-offs. Teams must weigh factors such as the threat model, the performance overhead they can tolerate, and the operational complexity of each primitive — considerations covered in more detail in subsequent deep dives on VMs and on containers with seccomp.
Choosing the right sandbox
Every sandboxing approach involves trade-offs between security, development effort, and runtime performance. The gaps between these factors can be significant. A seccomp-based solution typically offers strong security with minimal runtime overhead, but requires substantial upfront engineering. A container-based approach is much easier to ship but comes with more potential security pitfalls and often reduced performance.
Before committing to a specific technology, work through the following questions with your team. They map your requirements to the trade-offs each sandboxing model makes.
Environment
- Does the workload require a specific OS or other specialized runtime environment?
Security and performance
- How strong does the sandbox need to be, and how much attack surface is acceptable?
- What granularity of isolation is required: per job, per user, or per project, team, or organization?
- Are you willing to trade isolation strength for lower latency or reduced infrastructure costs?
- What are your compute budget and latency constraints?
Development costs and friction
- Does your team have the expertise to modify workload code for a tailored sandbox, or do you need a drop-in, off-the-shelf solution? Is an intermediate option acceptable?
- How much development complexity are you prepared to take on?
Maintenance and operational overhead
- Is the workload code under active development?
- Does another team own this system, and will they bear the operational burden?
- What level of debugging access will engineers require?
- Are you prepared to run and maintain the service yourself?
Sandboxing is a core tool for isolating risky workloads. At Figma, it enables new product features without exposing infrastructure to unnecessary risk or inflating the cost of each addition. Deeper dives into specific technologies, including how Figma applies them in production, are covered in the companion guides to virtual machines and containers and seccomp. 



