Como a Figma colocou no navegador uma ferramenta de design com cara de motor de jogo
A Figma é uma ferramenta de design em que o time inteiro edita o mesmo arquivo ao vivo no navegador. O canvas é C++ compilado para WebAssembly, com uma interface em React e TypeScript em volta, apoiado num servidor multiplayer em Rust, num monólito em Ruby e numa frota de Postgres bem fatiada na AWS.
Por quê: O ECS não tinha StatefulSets nem suporte a Helm, e o Kubernetes traz um ecossistema grande, menos dependência de um fornecedor e contratação mais fácil.
A Figma diz que o stack dela parece mais de motor de jogo que de app web. O canvas é escrito em C++, linguagem que os motores de jogo usam pela eficiência e pelo controle de memória, e compilado para WebAssembly. A troca para WebAssembly em 2017 deixou o carregamento mais de 3 vezes mais rápido.
O C++ não tem boas bibliotecas para interfaces ágeis, então tudo ao redor do canvas é feito em React e TypeScript.
O servidor multiplayer, que sincroniza cada edição, nasceu em TypeScript no Node.js. Com o crescimento, o modelo de uma thread só fazia uma operação lenta travar todo mundo no mesmo worker, e a coleta de lixo causava picos de latência imprevisíveis.
Em 2018 o time reescreveu em Rust a parte sensível a desempenho, rodando como um processo filho por documento, e a parte de rede ficou no Node.js. O Rust trouxe pouco consumo de recursos e segurança, sem a ergonomia difícil do C++.
Em 2020 a Figma rodava um único Postgres na maior máquina da AWS. No fim de 2022 já eram uns doze bancos separados por grupos de tabelas no Amazon RDS, mas algumas tabelas tinham chegado a terabytes e bilhões de linhas. Em 2023 o time lançou o sharding horizontal atrás de um serviço novo em Go, o DBProxy.
Foram avaliados CockroachDB, TiDB, Spanner e Vitess, além de NoSQL. Trocar exigiria uma migração de dados arriscada e jogaria fora anos de experiência com Postgres, com poucos meses de folga. E o NoSQL não tinha a flexibilidade relacional de que dependiam.
Os serviços da Figma já rodavam em contêineres no ECS da AWS, mas o ECS estava complicando a vida: não tinha StatefulSets para o etcd, não rodava fácil charts de Helm como o do Temporal e demorava para mudar o balanceador numa emergência. Em 2023 o time foi para o EKS, e em janeiro de 2024 o monólito e o multiplayer já rodavam em três clusters ativos.
Para quem desenvolve, nada mudou: cada serviço é descrito num arquivo de configuração do Bazel e a CI gera o YAML do Kubernetes. O ajuste automático de máquinas com Karpenter baixou o custo.
O visualizador de protótipos e o motor de reprodução no celular da Figma eram escritos em Skew, uma linguagem própria que compila para JavaScript. Era difícil de aprender para quem chegava e não conversava com o resto do código.
Quando os navegadores de celular passaram a suportar WebAssembly e os trechos mais pesados puderam ir para o motor em C++, a Figma escreveu um tradutor de Skew para TypeScript e migrou em três fases, sem parar o trabalho em recursos. Em 2024 o TypeScript virou a fonte oficial.