Escalabilidade
Escala vertical e horizontal, e o que precisa mudar no sistema para ele aceitar mais máquinas.
As decisões de escala são quatro: o que precisa mudar na aplicação para ela rodar em várias cópias, como escalar o banco de dados, quando escalar automaticamente e o que medir antes de qualquer coisa.
Preparar a aplicação para várias cópias
Cada tipo de estado que hoje mora na instância tem um lugar para onde ir:
| Estado | Para onde vai | Observação |
|---|---|---|
| Sessões | Redis, banco de dados, ou um token assinado no próprio cliente | O tópico de autenticação compara as opções |
| Arquivos enviados | Armazenamento de objetos (S3, GCS, Azure Blob, MinIO) | Com upload direto do navegador, os arquivos nem passam pela aplicação |
| Cache | Redis para dados compartilhados; memória só para dados de referência, com TTL curto | O tópico de cache detalha |
| Tarefas agendadas | Um agendador externo, ou uma trava que garante uma única execução | Ver abaixo |
| Limites de requisições | Contadores no Redis | Contados por usuário em todas as cópias |
| Conexões em tempo real | Um canal de publicação e assinatura entre as cópias | Uma mensagem para o usuário precisa chegar à cópia em que ele está conectado |
| Configuração | Variáveis de ambiente ou um serviço de configuração | Nunca editar arquivos dentro de uma cópia em execução |
Afinidade de sessão não é a solução
Os balanceadores oferecem afinidade de sessão (sticky sessions): o mesmo usuário vai sempre para a mesma cópia. Ela esconde o problema do estado na memória, mas não o resolve:
- quando a cópia cai ou é substituída num deploy, os usuários dela perdem o estado;
- a carga fica desigual, porque alguns usuários fazem muito mais pedidos que outros;
- a escala automática fica lenta para reduzir, porque cada cópia tem usuários presos a ela.
Ela tem usos legítimos, como reduzir a troca de servidor em conexões de longa duração. Como forma de guardar estado, é um adiamento.
Tarefas agendadas com várias cópias
| Abordagem | Como funciona |
|---|---|
| Agendador externo | Um CronJob do Kubernetes ou um agendador da nuvem dispara a tarefa uma vez, fora das cópias da aplicação |
| Trava no banco | Todas as cópias tentam rodar; só a que obtém a trava executa |
| Fila de tarefas | O agendador publica uma mensagem, e um único consumidor a processa |
A trava no banco é a solução mais simples quando já existe um PostgreSQL. O nível Implementação mostra como.
Escalar o banco de dados
O banco é a parte mais difícil de escalar, porque guarda o estado que a aplicação tirou de si. A ordem abaixo vai do mais barato para o mais caro, e a maioria dos sistemas nunca passa do meio da lista.
| Degrau | O que fazer | Custo |
|---|---|---|
| 1. Otimizar consultas | Índices, eliminar N+1, conferir planos de execução | Baixo; costuma render mais que todo o resto |
| 2. Pool de conexões | Limitar e reaproveitar conexões; um intermediário como PgBouncer com muitas cópias da aplicação | Baixo |
| 3. Cache | Tirar do banco as leituras repetidas | Médio; traz o problema da invalidação |
| 4. Escala vertical | Uma máquina maior para o banco | Médio; simples, com teto alto |
| 5. Réplicas de leitura | Leituras distribuídas entre cópias | Médio; traz atraso de replicação |
| 6. Particionar tabelas | Dividir tabelas enormes por data ou por chave, no mesmo servidor | Médio |
| 7. Separar bancos por domínio | Pedidos num banco, catálogo em outro | Alto; junções entre domínios deixam de existir |
| 8. Sharding | Dividir os mesmos dados entre vários servidores, por chave | Muito alto; afeta consultas, transações e operação |
Escala automática
| Métrica para escalar | Quando usar | Cuidado |
|---|---|---|
| Uso de CPU | Aplicações que gastam CPU por pedido | Não reage a gargalos de entrada e saída |
| Pedidos por segundo por cópia | APIs com custo parecido por pedido | Exige saber quantos pedidos uma cópia aguenta |
| Tamanho da fila | Consumidores de mensagens | O indicador mais direto para trabalho assíncrono |
| Latência | Quando a experiência é o que importa | Se o gargalo for o banco, mais cópias pioram a latência |
Três regras evitam os problemas mais comuns:
- Um mínimo de pelo menos duas cópias, para que a queda de uma não derrube o sistema.
- Um máximo, calculado pelo que o banco e as dependências aguentam.
- Reduzir mais devagar do que aumentar, para não remover cópias que serão necessárias minutos depois.
Medir antes de escalar
| Pergunta | Onde olhar |
|---|---|
| Onde o tempo de cada pedido é gasto? | Rastreamento distribuído, profiling |
| Qual recurso está no limite? | CPU, memória, conexões e disco de cada componente |
| Quantos pedidos uma cópia aguenta? | Teste de carga numa cópia isolada |
| Qual é o primeiro componente a falhar com o dobro da carga? | Teste de carga no sistema inteiro |
Um teste de carga antes de um evento esperado, como uma promoção, mostra onde o sistema vai quebrar enquanto ainda há tempo de agir. O tópico de testes de carga aprofunda.
Resumo da decisão
- Meça primeiro: escala resolve capacidade, e não lentidão de um pedido.
- Aplicação sem estado: sessões, arquivos, cache e tarefas fora da instância.
- Banco: otimizar, cache, máquina maior e réplicas, nessa ordem, antes de dividir dados.
- Escala automática com mínimo de duas cópias, máximo calculado e redução lenta.
- Cópias descartáveis: iniciam rápido e saem sem derrubar pedidos.
O próximo nível mostra o encerramento gracioso nas cinco linguagens, as verificações de saúde e a trava para tarefas agendadas.
Prompts para aprofundar
Ao abrir no ChatGPT ou no Claude, o prompt é enviado ao serviço escolhido pela URL e também fica copiado na sua área de transferência.
Preparar a aplicação para várias cópias
Quero preparar a minha aplicação para rodar em várias cópias atrás de um balanceador. Pergunte qual linguagem, framework e infraestrutura eu uso, e peça que eu descreva o que a aplicação guarda hoje: sessões, uploads, cache, tarefas agendadas, conexões em tempo real e configuração. Para cada item: 1. Diga se ele impede a escala horizontal e por quê. 2. Proponha para onde ele deve ir, com a opção mais simples para o meu caso. 3. Estime o esforço da mudança. Explique também por que a afinidade de sessão esconde o problema em vez de resolvê-lo. Termine com um plano em ordem de prioridade e com a forma de testar localmente, com duas cópias atrás de um balanceador, que tudo funciona.
Escalar o banco de dados sem pular etapas
Meu banco de dados está chegando ao limite e quero escolher o próximo passo certo. Faça estas perguntas, uma por vez: - Qual banco eu uso e em que máquina ele roda? - O que está no limite: CPU, memória, disco, conexões? - A carga é mais de leitura ou de escrita? - Quais são as consultas mais pesadas? - Quantas cópias da aplicação existem e qual é o tamanho de cada pool de conexões? Com as respostas, percorra comigo a escada: otimizar consultas, pool e intermediário de conexões, cache, máquina maior, réplicas de leitura, particionamento de tabelas, separação por domínio e sharding. Para cada degrau, diga se ele resolve o meu problema, o que custa e o que muda na aplicação. Recomende o próximo passo e o que medir para saber se funcionou.
Configurar a escala automática
Quero configurar a escala automática da minha aplicação sem criar novos problemas. Pergunte onde a aplicação roda (Kubernetes, serviço de containers da nuvem, máquinas virtuais) e que tipo de carga ela tem. Explique: 1. Qual métrica usar para escalar no meu caso: CPU, pedidos por segundo, tamanho de fila ou latência. 2. Como escolher o mínimo e o máximo de cópias, considerando o que o banco e as outras dependências aguentam. 3. Por que reduzir deve ser mais lento que aumentar. 4. Como o tempo de inicialização das cópias afeta a reação a picos. 5. Como testar a configuração antes de um evento real. Termine com a configuração recomendada para a minha plataforma.