Arquitetura Baseada em Células Não É de Graça: O Que Slack, DoorDash e Roblox Realmente Pagaram Por Ela
Arquitetura baseada em células contém o raio de impacto, mas não é gratuita. Um olhar sobre o que Slack, DoorDash e Roblox realmente pagaram por células em produção — e um checklist para os padrões mais baratos de isolamento de falhas que a maioria dos times deveria considerar primeiro.
Células voltaram ao roadmap. Uma em cada duas palestras sobre resiliência desta primavera tem um slide que coloca Slack, DoorDash e Roblox no mesmo quadro e conclui com "é para cá que estamos indo". O padrão é real, os benefícios são reais, e os write-ups de produção valem a leitura. Mas o custo das células também é real, e na maioria das salas onde esse slide é exibido, o time não está pronto para pagá-lo.
Uma célula é um anteparo (bulkhead) com um orçamento. Você escolhe uma fronteira — uma availability zone, um shard de cliente, um tipo de workload — e reconstrói seu stack para que toda dependência dentro daquela fronteira seja independente de qualquer outra célula. O roteamento fica por cima. Quando uma célula pega fogo, ela pega fogo sozinha. Esse é o pitch inteiro, e ele é convincente quando você acabou de ver uma única configuração ruim se propagar por todas as regiões que você tem.
O problema é que essa fronteira é estrutural. Tudo que você adiciona — um novo serviço, um novo banco de dados, um novo job em background — tem que decidir de que lado da linha fica, e a resposta errada destrói silenciosamente o isolamento que você achava que tinha. Essa é a parte que as palestras de conferência subvalorizam.
O que Slack, DoorDash e Roblox realmente consertaram
A migração do Slack para celular começou depois de uma série de incidentes de rede em nível de AZ e de control plane que transformaram o dia ruim de uma única zona em horas de serviço degradado para todo cliente. A correção foi fazer a porta de entrada — roteamento, Envoy, a camada de sessão — ser ciente de zonas, e então alinhar os serviços stateful atrás dela para que uma falha de zona drenasse de forma limpa. A métrica principal não é "menos falhas", mas "raio de impacto menor": quando uma zona se comporta mal, o dano para na fronteira da zona em vez de atravessar o fabric de rede.
A história do DoorDash é adjacente mas não idêntica. O trabalho deles em roteamento zone-aware no Envoy saiu de um problema de tráfego cross-AZ, não de um problema puro de isolamento — hops entre zonas estavam adicionando latência e custo em uma escala em que ambos importavam. Isolamento foi um efeito colateral de manter o tráfego local. A lição que a maioria dos times tira do DoorDash é "faça células"; a lição que deveriam tirar é "a maior parte do seu tráfego não tinha por que sair da zona em primeiro lugar".
A reorganização pós-incidente do Roblox foi a professora mais dura. Uma falha em cascata num componente de control plane compartilhado tirou a plataforma do ar durante a maior parte de três dias. A correção foi mais profunda do que roteamento: envolveu quebrar dependências compartilhadas, mudar como clusters eram provisionados, e tratar o raio de impacto como um alvo de design de primeira classe. Células foram parte da resposta. Assim como podar agressivamente o que o control plane tinha permissão de fazer.
O que essas três histórias têm em comum não é "construímos células e tudo melhorou". É "tínhamos um modo de falha específico que um substrato compartilhado agravava, e celularizar o substrato foi mais barato do que endurecê-lo".
Anatomia de uma célula e onde o custo se esconde

Uma célula é três coisas empilhadas. Uma camada de roteamento no topo que sabe a qual célula uma requisição pertence. Um conjunto de serviços e dados locais da célula por baixo, sem chamadas cross-cell no caminho quente. E um control plane ao lado que provisiona células, aloca tenants, drena tráfego e possui tudo que genuinamente precisa ser global.
Cada uma dessas três camadas tem um custo que a maioria dos roadmaps subestima.
A camada de roteamento é a parte em que os times mais erram. "Roteamento cell-aware" soa como uma mudança de configuração. Na prática é uma nova frota: você é dono do roteador, da sua cadência de deploy, de sua observabilidade e — o pior de tudo — dos seus modos de falha. Um roteador bugado cancela toda a isolação que você pagou, porque uma requisição roteada para a célula errada agora é uma dependência cross-cell sem circuit breaker. Slack e DoorDash se apoiam no Envoy por uma razão: é um data plane maduro com uma história crível para zone awareness. Construir o seu próprio no tier de um gateway Kotlin/Spring é um projeto de dois quartos que parece duas sprints no quadro branco.
A camada de dados local da célula é onde o diagrama de arquitetura deixa de ser honesto. Se cada célula tem seu próprio banco de dados, você acabou de multiplicar sua superfície operacional pelo número de células. Backups, failovers, migrações de schema, lag de read-replica, capacity planning — tudo isso, por célula. Os times compensam encolhendo o raio de impacto de cada célula, o que significa mais células, o que significa mais data planes para operar. Esse é o custo que a maioria dos checklists de adoção passa batido em um único bullet e é onde mora a carga de on-call.
O control plane é a parte onde o padrão vaza silenciosamente. Um modelo puro de células diz que nada atravessa a fronteira no caminho quente, mas o control plane ainda precisa alocar tenants, movê-los entre células, e lidar com features cross-cell. Busca, analytics, contadores globais, rate limits que abarcam toda a base de usuários — nada disso quer viver dentro de uma célula. A maioria dos times acaba com um tier "global" parafusado em cima, e esse tier se torna exatamente o destino compartilhado que as células eram supostas eliminar. O postmortem do Roblox é, em parte, uma história sobre esse tier ter sido subestimado.
As coisas mais baratas que costumam vir antes
Para um número surpreendente de sistemas, a resposta certa não é células. É um dos três padrões que células subsumem, aplicado deliberadamente e sem o imposto operacional.
Roteamento zone-aware é o primeiro. Mantenha o tráfego dentro da zona em que entrou; faça fallback entre zonas só quando o alvo local está doente. Isso resolve a maioria dos incidentes do tipo "uma AZ teve um dia ruim" que motivam palestras sobre células, custa quase nada se você já roda um service mesh, e não exige que você reconstrua sua camada de dados. O trabalho do DoorDash é tanto um argumento para roteamento zone-aware quanto para células.
Shuffle sharding é o segundo. Em vez de rodar cada tenant em cada nó, você atribui a cada tenant um pequeno subconjunto aleatório da frota. Um vizinho barulhento ou um tenant mal-comportado só pode prejudicar o pequeno grupo de outros tenants que compartilham seu shuffle. Esse é o padrão que a AWS usa silenciosamente há anos e ele te dá 80% da redução de raio de impacto das células com uma fração da superfície operacional. Se sua dor é "um cliente pode prejudicar todos os outros", shuffle sharding é quase sempre a resposta mais barata.
Workloads particionados é o terceiro. Boa parte da adoção de células é na verdade sobre separar workloads que nunca deveriam ter compartilhado um cluster: jobs batch ao lado de tráfego interativo, entrega de webhooks ao lado de APIs voltadas ao usuário, um único consumer group Kafka lidando com três pipelines não relacionados. Separar isso é barato, elimina uma classe real de incidentes, e não requer um roteador, um control plane ou bancos de dados por célula.
Se você ainda não fez esses três, você não está pronto para células — você está pronto para uma vitória mais fácil.
Quando células são de fato a ferramenta certa
Os sinais são específicos o suficiente para enumerar. Você deveria considerar células quando todos esses são verdade, não só alguns.
Seu alvo de disponibilidade é alto o bastante para que uma falha de região única com control plane único vá violar seu SLO por si só. Se um evento de três horas de AZ é sobrevivível para o seu negócio, você quase certamente não precisa de células.
Você já esgotou roteamento zone-aware, shuffle sharding e particionamento de workload, e ainda vê incidentes em que os problemas de uma coorte vazam para todas as outras. Os vazamentos remanescentes estão em substrato compartilhado, não em código de aplicação.
Você tem um owner crível para o roteador e o control plane. Não um time que os construirá como um projeto paralelo, mas um time cujo roadmap e rotação de on-call é explicitamente "a infraestrutura de células". Slack, DoorDash e Roblox todos têm esse time. A maioria das empresas que citam essas palestras não tem.
Você consegue nomear a coisa que quer que seja local à célula — processamento de requisições, dados de cliente, um pipeline específico — e a coisa com a qual você fica confortável deixar global. Se todo serviço quer ser local à célula, você está descrevendo uma região, não uma célula, e deveria apenas rodar outra região.
Você está disposto a pagar um imposto de latência e custo em features cross-cell para sempre. Busca global, analytics global, features cross-tenant, anti-abuso — tudo isso será mais difícil, mais lento ou mais caro. Se a liderança se surpreende com isso no ano dois, o programa será revertido.
Se você for fazer isso mesmo assim
Comece com uma célula por availability zone, não uma célula por cliente. Células do tamanho de zonas casam com seus domínios de falha existentes, te permitem reutilizar seu service mesh para roteamento, e te dão uma implementação de referência funcional sem o debate de "quantas células?". Cresça para células mais granulares depois, só para os workloads que demonstravelmente precisam.
Construa o roteador e o control plane como produtos, não como encanamento. Dê a eles um owner, um SLO e um runbook. Trate "uma célula foi roteada para o lugar errado" como um incidente severo, porque é: é o único modo de falha que silenciosamente apaga todo o valor do padrão.
Escreva as features cross-cell no dia um. Busca, analytics, billing, anti-abuso, rate limits globais, ferramentas admin — liste-as, decida qual tier é dono delas, e aceite que é aí que foi parar a complexidade. Se a lista está vazia, você está mentindo para si mesmo.
Meça raio de impacto, não uptime. Células raramente reduzem o número de incidentes; elas reduzem a fração de usuários afetados por incidente. Se seus dashboards não conseguem mostrar "porcentagem de tráfego degradado durante o último incidente", você não vai conseguir dizer se o programa está funcionando.
Conclusões
- Células são um anteparo em escala. O benefício é raio de impacto contido; o custo é um roteador, um control plane e uma superfície operacional por célula que cresce com o número de células.
- As histórias de Slack, DoorDash e Roblox são sobre modos de falha específicos de substrato compartilhado. Copie o padrão só se você tem o mesmo modo de falha.
- Roteamento zone-aware, shuffle sharding e particionamento de workload resolvem a maioria do que motiva a adoção de células, a uma fração do custo operacional.
- Features cross-cell — busca, analytics, contadores globais, identidade — são para onde a complexidade silenciosamente se muda. Se elas não forem nomeadas no dia um, vão comer o programa.
- Comece com células do tamanho de zonas, seja dono do roteador e do control plane como produtos, e meça raio de impacto como um SLO de primeira classe.
Recorra a células quando você tem um alvo de disponibilidade que um único substrato compartilhado não consegue atingir, um time para ser dono da infraestrutura de células como produto, e tolerância para fricção cross-cell permanente. Evite-as quando um conjunto menor de padrões plausivelmente fecharia a lacuna, ou quando "precisamos de células" está sendo dirigido pelo circuito de conferências em vez de pela sua história de incidentes.