Nos capítulos anteriores da série System Design: da teoria à prática, já falamos sobre trade-offs inevitáveis, confiabilidade, consistência e como observar sistemas em produção. Agora entramos em um tema que costuma gerar debates intensos entre engenheiros, arquitetos e gestores: como equilibrar performance e custo em sistemas modernos.
Essa discussão não é trivial. Performance não é apenas velocidade, mas previsibilidade e experiência do usuário. Custo não é só dinheiro, mas também tempo de desenvolvimento, complexidade operacional e dívida técnica acumulada.
Muitas vezes, tentar otimizar tudo ao mesmo tempo é impossível. E, se não formos criteriosos, acabamos caindo na armadilha de gastar milhões para ganhar milissegundos em pontos que não movem o ponteiro do negócio.
Neste artigo, vamos destrinchar cinco princípios fundamentais:
- Otimize o hot path, não o cold path.
- A maioria dos gargalos vive no banco de dados, não no código.
- Escala horizontal vence a vertical — até a coordenação matar.
- Warm caches mascaram queries ruins.
- O recurso mais barato é disco; o mais caro é tempo.
26. Otimize o hot path, não o cold path
Teoria. Em qualquer sistema, nem todas as rotas de execução são igualmente importantes. O hot path é o caminho crítico, percorrido pela maioria das requisições, onde cada milissegundo importa. Já o cold path são rotas raras, acessadas esporadicamente, onde otimizações custam caro e trazem pouco retorno.
Um erro comum é gastar semanas ajustando cold paths que quase nunca são executados, em vez de atacar o hot path. Em sistemas de alto tráfego, 80% da experiência do usuário está em 20% do código — e esse é o lugar onde cada melhoria traz impacto perceptível.
Prática. Identificar o hot path exige métricas e tracing. Ferramentas como Datadog APM, OpenTelemetry ou New Relic ajudam a visualizar onde está o tempo de resposta real. Só então faz sentido aplicar otimizações como:
- Reduzir round-trips em chamadas de rede.
- Colocar caches específicos.
- Diminuir complexidade algorítmica em loops de alto volume.
Exemplo real. A Amazon descobriu que, no checkout, a parte mais crítica não era o cálculo de frete em si, mas a renderização da página de pagamento — qualquer atraso ali gerava abandono. Investiram pesado em otimizar esse hot path, deixando cálculos de menor impacto para rodar em paralelo ou de forma assíncrona.
👉 Esse princípio conecta diretamente ao artigo Como a Uber calcula o tempo estimado de chegada, onde mostramos que otimizar o que o usuário percebe (latência visível) é mais importante do que ajustar detalhes internos invisíveis.
27. A maioria dos gargalos vive no banco de dados, não no código
Teoria. É comum engenheiros tentarem otimizar o código da aplicação — micro-otimizações, mudanças em algoritmos — quando o gargalo real está no banco de dados. Consultas mal escritas, índices ausentes ou schema mal projetado costumam representar mais de 70% da latência em sistemas corporativos.
Enquanto CPU e memória são baratos, cada round-trip ao banco carrega custo de rede, bloqueios, parsing de query e execução em disco. E, diferentemente de código, bancos lidam com concorrência massiva. Uma query ruim não degrada só uma requisição, mas pode derrubar a performance do cluster inteiro.
Prática. Diagnosticar gargalos exige analisar query plans, métricas de I/O e locks. Algumas práticas:
- Garantir índices seletivos nos campos corretos.
- Evitar N+1 queries (ex.: resolvendo via
JOIN
ouIN
). - Monitorar queries longas via slow query log.
- Revisar cardinalidade — tema já explorado em Cardinalidade: o conceito que transforma o desempenho de bancos de dados SQL e NoSQL.
Exemplo real. No LinkedIn, uma query não indexada em uma tabela de bilhões de registros travava relatórios críticos. A correção — adicionar um índice composto simples — reduziu o tempo de execução de 3 horas para menos de 1 minuto. O código da aplicação não precisou mudar em nada.
28. Escala horizontal vence a vertical — até a coordenação matar
Teoria. Escalar verticalmente (aumentando CPU, memória ou disco em um único servidor) tem limites físicos e financeiros. Escalar horizontalmente (adicionar mais nós) é quase sempre mais viável a longo prazo. Mas horizontalidade traz novos problemas: coordenação, consistência, balanceamento.
É aqui que entra o famoso CAP theorem: não dá para ter consistência forte, disponibilidade e tolerância a partições ao mesmo tempo. Cada escolha de arquitetura horizontal exige trade-offs.
Prática. Para escalar horizontalmente sem perder o controle:
- Use sharding com chaves bem escolhidas (evitando hot partitions).
- Adote coordenação leve: gossip protocols, caches distribuídos e particionamento por domínio.
- Evite locks distribuídos sempre que possível; prefira designs que toleram inconsistência temporária.
Exemplo real. O Instagram, ao migrar para Cassandra, enfrentou dores sérias de rebalances e hot partitions. Resolveram adotando chaves compostas e políticas de replicação ajustadas ao uso real. A horizontalidade deu escala, mas o custo de coordenação exigiu maturidade de engenharia.
29. Warm caches mascaram queries ruins
Teoria. Um sistema pode parecer rápido porque está respondendo com dados em cache, mas isso mascara a realidade: queries ruins ainda estão lá, apenas escondidas. Se o cache expirar (ou em caso de cold start), o sistema pode colapsar de repente.
Warm caches são úteis, mas perigosos quando viram muleta. Sem medir cache miss latency, é impossível saber se o sistema realmente está preparado para lidar com tráfego frio.
Prática. Estratégias para não cair na armadilha:
- Monitorar cache hit ratio e latência de misses.
- Usar cache warming para pré-carregar dados críticos.
- Revisar queries mesmo que o cache as esconda.
- Balancear TTLs curtos (dados frescos) com custos de recomputação.
Exemplo real. Em 2020, um e-commerce global sofreu outage porque uma falha em Redis invalidou milhões de chaves. O banco de dados, acostumado a trafegar 5% da carga, recebeu 100% em minutos e colapsou. O problema não era falta de cache, mas dependência excessiva sem revisar queries subjacentes.
👉 Esse tema se conecta ao artigo Cache Hit Ratio: entenda a métrica que revela a saúde do seu cache, onde mostramos como medir e interpretar o impacto real de caches.
30. O recurso mais barato é disco; o mais caro é tempo
Teoria. No passado, armazenar dados era caro e CPU era escassa. Hoje, o cenário se inverteu: disco e memória estão mais baratos do que nunca, mas o tempo de engenheiros e a latência percebida pelos usuários são os ativos mais caros.
Isso muda a forma de projetar sistemas: muitas vezes, vale a pena gastar mais disco para reduzir complexidade ou latência. Exemplos:
- Pré-computar resultados e armazená-los.
- Manter históricos em vez de sobrescrever.
- Duplicar dados em múltiplos formatos para acesso otimizado.
Prática. O desafio é usar disco de forma consciente: armazenar tudo sem critérios gera custos invisíveis (backups, replicação, governança). Mas evitar redundância a qualquer custo pode resultar em sistemas lentos e caros em tempo de engenharia.
Exemplo real. O Snowflake adota o princípio de separar storage de compute. O storage pode crescer quase ilimitadamente a baixo custo; o compute é pago conforme uso. Isso força empresas a entenderem que guardar dados é barato, mas processá-los rápido é o que realmente custa.
Conclusão — performance é tempo, custo é escolha
Performance e custo não são opostos, mas dimensões diferentes da mesma decisão. Em alguns casos, vale gastar dinheiro para economizar tempo do usuário (otimizando o hot path). Em outros, vale aceitar latência maior para reduzir custos financeiros. O ponto é que cada escolha deve ser explícita e contextual.
Recapitulando:
- Otimize o que importa para o usuário, não o que é raro.
- Olhe para o banco de dados antes de mexer no código.
- Escale horizontalmente, mas reconheça o custo de coordenação.
- Não use caches como muleta para queries ruins.
- Gaste disco, mas economize tempo.
No fundo, o que mais custa em sistemas distribuídos é tempo: do usuário que espera, da equipe que corrige, da empresa que perde oportunidade. E a melhor arquitetura é aquela que sabe onde investir cada recurso de forma consciente.
No próximo capítulo, fecharemos a série com Pessoas e Processos: como cultura, revisões e papéis de engenharia moldam sistemas tão fortemente quanto código ou infraestrutura.