A proxy layer for Figma's ephemeral data

Figma’s storage infrastructure has undergone two major overhauls in recent years. After rearchitecting its durable metadata storage in 2024, the company turned its attention in 2025 to the ephemeral layer built on Redis. The result is FigCache: a stateless proxy service that presents a unified Redis data plane, paired with first-party client libraries.

FigCache decouples Redis connection scalability from client fleet volatility, centralizes traffic routing, and improves security and observability across the caching stack. Since its rollout for Figma’s main API service in the second half of 2025, the caching layer has achieved six nines of uptime.

Why Redis became a bottleneck

Redis evolved from a non-critical component into a critical-path dependency as Figma scaled. The problems were structural:

  • Redis clusters faced growing connection volumes approaching hard limits.
  • Rapid scale-ups of client services produced thundering herds of connection establishment that bottlenecked I/O.
  • Lack of centralized traffic management led to data pollution or corruption across clusters.
  • Inconsistent observability across client libraries made incident diagnosis slow.
  • A fragmented client ecosystem prevented fleet-wide guarantees about client-side state during failovers or topology changes.

Early mitigation efforts included removing Redis dependencies from core API subsystems and building a service-specific client-side connection pooling layer. Both isolated Redis outages from top-level site availability but were localized fixes. The team wanted a more strategic, long-term solution.

Design objectives for a next-generation platform

Figma set concrete goals for the rearchitecture, with a multi-year horizon:

  • Isolate Redis from client connection volatility. Connection volume served by Redis should not depend on client application size or elasticity, and Redis should be protected from thundering herds during scale-ups.
  • Supply batteries-included observability. Consistent, multi-layered, granular monitoring for both service owners and platform operators in a multitenant environment.
  • Expose transparent, elastic horizontal scalability. Clients should not handle cluster topology changes—scale-outs, scale-ins, node failovers, total shard losses—themselves. The complexity of the Redis Cluster protocol should be abstracted below the client layer.
  • Abstract multiple backends behind a universal endpoint. Traffic routing between applications and clusters should be mediated by a centralized source of truth, removing application-level endpoint configuration complexity.
  • Support pluggable backend storage. The platform should accommodate new workloads with minimal client changes, including opt-in true durability backed by alternative storage technologies behind the same protocol and API.
  • Be extensible by default. Custom, Figma-specific data plane logic—inline data encryption, guardrail enforcement, traffic backpressuring—should be abstracted away from applications.

The architecture: proxy plus client libraries

Figma settled on two key pieces of infrastructure. First, a caching proxy service acting as a unified Redis data plane and ingress layer. It provides a language-agnostic interface to Redis, acts as a connection multiplexer, and implements a standardized observability system for all Redis traffic.

Second, first-party, cross-language client libraries that establish a Figma-wide baseline for supported client features and vetted configuration parameters. To minimize disruption, the team built wrappers over the existing open source Redis client libraries already in use, avoiding a proprietary protocol or a wholesale client migration.

Delivery followed a three-phase plan:

  1. Develop opinionated, first-party clients in Go, Ruby, and Typescript; migrate all services to these clients without changing endpoints.
  2. Build and productionize the internal Redis proxy, addressing scalability, reliability, operability, and observability at that layer.
  3. Migrate applications to the proxy gradually, with a rollout sequence trading off site availability risk against reliability gains.

Build over buy

Figma evaluated open source solutions against its requirements before committing to an in-house build. Existing proxies had limitations that made them a poor fit:

Their RPC servers could not extract full, annotated arguments from arbitrary inbound Redis commands. That lack of semantic awareness prevented building generic, comprehensive runtime guardrails. It also blocked defining custom commands intercepted and executed by the proxy itself—including a language-agnostic, multi-cluster distributed locking abstraction over Redlock and a protocol-native graceful connection draining mechanism for rapid deployments.

The fragmented client ecosystem was another obstacle. Applications connected to Redis with various combinations of Cluster-awareness, TLS in-transit encryption, and other parameters. A proprietary proxy allowed building shims in the RPC layer to handle these quirks transparently—such as a Redis Cluster mode emulation layer that presents the proxy to cluster-aware clients as a fake cluster.

Finally, extending existing open source proxies with custom logic would require maintaining a source code fork that would be difficult to keep in sync with upstream. Figma designed its proxy to be internally composable, making it straightforward to extend command processing and execution with proprietary logic. This supports forward-looking features like priority-aware traffic load control (QoS-based backpressuring), inline data encryption and compression, multi-upstream traffic mirroring, and highly customizable command usage restrictions.

A stateless Redis proxy

Figma's solution, called FigCache, is a stateless proxy service that speaks the Redis Serialization Protocol (RESP) on the wire and sits in front of a fleet of Redis clusters on AWS ElastiCache. The proxy is complemented by first-party client libraries that maintain interface compatibility with existing open source Redis clients, so adoption is a low-friction change for most applications.

The proxy's internal architecture separates frontends from backends. The frontend layer handles all client interaction: RESP-based RPC, network I/O, connection management, and protocol-aware command parsing. The backend layer is responsible for command processing, connection multiplexing to storage backends, and physical command execution. This decoupling was deliberate, allowing FigCache to expose alternative frontends for services that don't use RESP or Redis clients and to plug in different storage backends, such as durable Redis alternatives like AWS MemoryDB or Figma's in-house horizontally sharded Postgres stack.

The frontend also includes a composable inline request and response manipulation engine, enabling read/write connection splitting, key pattern-based routing, and internally parallelized scatter-gather execution.

Client requests flow through a load balancer to distributed FigCache nodes that interact with standalone and clustered Redis instances.
FigCache is a stateless, highly available, and horizontally scalable service that proxies connections to ElastiCache Redis clusters.

A drop-in replacement

For most applications, migrating to FigCache is as simple as changing a one-line endpoint configuration. The proxy absorbs the burden of connection pooling, traffic routing, and observability, isolating Redis from the cost of client-side connection establishment.

To make this work, the team built ResPC, a Go RPC framework for building servers over RESP. ResPC sits at the entry point to FigCache's core command processing engine and comprises several independent components:

  • Server layer: Accepts connections, manages in-memory client state, and handles network I/O.
  • Streaming RESP protocol parser: Incrementally parses and serializes RESP messages over the wire.
  • Schema-driven structured command parser: Uses a declarative schema registry to derive semantic meaning from RESP commands.
  • Command dispatch layer: Performs implementation-agnostic command processing, which in FigCache means dispatching commands to upstream clusters.
Layered pipeline illustrating networking, I/O, parsing, and execution stages for processing RESP protocol commands.
ResPC derives structured, semantically rich RESP commands from a stream of raw bytes issued by Redis clients.

Configuration-driven routing

FigCache's backend is modeled as a tree of engine nodes assembled at runtime. Leaf nodes are "data engines" that execute commands against Redis. Intermediate "filter engines" route, block, or modify commands before passing them down. Processing a command is conceptually equivalent to running it through this directed graph from the root.

This design addresses a specific pain point with Redis cluster mode: multi-key operations like pipelines and transactions that span hash slots return CROSSSLOT errors, since they may be cross-shard and not guaranteed atomic or single-connection. FigCache's fanout filter engine intercepts eligible multi-shard pipelines and executes them as a parallelized scatter-gather, dispatching individual commands and aggregating responses. This transparently resolves read-only batch operations that would otherwise surface to clients as CROSSSLOT violations.

FigCache decomposes requests into parallel operations across Redis cluster shards and reassembles results.
The fanout execution engine internally resolves certain cross-shard, read-only pipelines as parallelized scatter-gathers.

The engine tree itself is expressed entirely in configuration. FigCache uses a custom configuration system that models engine setup as a Starlark program, evaluated at runtime in a VM, which produces a Protobuf-structured configuration consumed by the backend. Operators can express routing rules, key-prefix rejection, and connections to distinct clusters by composing a few primitive building blocks — no server code changes or binary deployments required.

Routing diagram showing commands directed through routers to different Redis instances or rejected based on rules.
Starlark configuration programs materialize a command execution graph that can be modeled as a tree, whose nodes are individual engines.
def main():
   """
   This configuration program expresses hierarchical evaluation
   of keys to conditionally serve or reject requests in two Redis
   clusters, foo and bar.
  
   It is modeled by composing two primitives--a Router, which
   splits execution among multiple child engines based on a match
   of the command schema or key pattern, and a Redis, which
   executes the command against a Redis cluster.

   GET commands are unconditionally served by redis-foo.
   SET commands are served by redis-bar, but only if its key
   starts with `bar:`; other keys are rejected with a static
   error message.
   """
   redis_foo = enginepb.Redis(...)
   redis_bar = enginepb.Redis(...)
  
   bar_router = enginepb.Router(
       rules = [
           enginepb.Rule(
               prefix = enginepb.Rule.Prefix(prefix = "bar:"),
               engine = redis_bar,
           ),
           enginepb.Rule(  # passthrough
               engine = enginepb.Static(
                   reply = respcpb.Reply(message = "rejected"),
               ),
           ),
       ],
   )
  
   cmd_router = enginepb.Router(
       rules = [
           enginepb.Rule(
               command = respcpb.Schema(name = "GET"),
               engine = redis_foo,
           ),
           enginepb.Rule(
               command = respcpb.Schema(name = "SET"),
               engine = bar_router,
           ),
       ],
   )
  
   return cmd_router

The migration playbook

The migration strategy was guided by several principles: build correctness confidence early through integration tests and synthetic load; minimize code changes required of client applications; provide granular switches for gradual traffic rollover; and ensure every change is reversible at runtime with feature flags.

Performance was the biggest risk. Adding a proxy tier introduces latency through extra network hops and I/O layers. To understand and mitigate this, the team ran extensive benchmark evaluations, including a distributed stress test that runs weekly on production and surges throughput to an order of magnitude above Figma's typical organic peak.

They also deployed routing-level configuration to probabilistically colocate traffic within the same AWS availability zone, avoiding cross-AZ network penalties that can add milliseconds. On the development side, continuous integration produces CPU and memory profiles for every pull request and hermetically runs synthetic benchmarks against the server, checking for regressions against a golden performance baseline.

What FigCache unlocked

In 2025, FigCache went live for several critical Figma services without disruption to availability or functionality.

Infrastructure scalability

As a connection pooling layer, FigCache fundamentally solves connection scalability. Figma's API fleet can now scale rapidly in response to user traffic without adverse effects on underlying Redis clusters, and connection pressure on the most critical clusters has been alleviated.

Line chart showing Redis server-side connection counts dropping sharply after July and stabilizing at lower levels.
Following the rollout for 100% of Redis traffic originating from Figma's main API service, connection counts on Redis clusters dropped by an order of magnitude across the board, and became significantly less volatile despite an unchanged, diurnal site traffic pattern.

Reliability improvements

Connection pooling eliminated an entire class of reliability risks around thundering herds of new client connections, a common theme in prior high-severity incidents. Standardizing on FigCache as a universal access tier also simplifies how ElastiCache operational events are handled: node failovers, cluster scaling, and transient connectivity errors are now zero-downtime events requiring no operator intervention.

End-to-end observability

The entire caching stack is now instrumented with metrics, logs, and traces. Automatic measurement of availability, throughput, latency, payload size, command cardinality, and connection distribution has cut incident diagnosis time from hours or days down to minutes.

FigCache's routing layer also ascribes ownership metadata to every inbound Redis command, allowing operational metrics to be sliced across hundreds of application workloads by tier, durability expectations, and consistency requirements. This work enabled Figma to formally define a caching platform SLO and precisely quantify the aggregate reliability profile of Redis across the company.

Routine operations

Hardware rotations, cluster topology changes, OS upgrades, and security updates previously required cross-team coordination and occasionally scheduled downtime. With FigCache, these are now routine background operations. Shard failovers in particular require zero operator involvement and are executed liberally and frequently — partly as a regular, production-environment exercise of the system's built-in resilience to Redis topology changes.