Scaling

Escopo: transversal. Aplica-se a qualquer linguagem ou stack do projeto.

Escalar um sistema é resolver um problema de capacidade: mais tráfego, mais dados, mais usuários simultâneos. A armadilha é investir em infraestrutura para um problema que ainda não existe. A postura correta: construir com base sólida e escalar quando os dados indicarem necessidade.

Conceitos fundamentais

ConceitoO que é
Vertical scaling (escala vertical)Aumentar CPU, RAM ou disco da máquina existente
Horizontal scaling (escala horizontal)Adicionar mais instâncias da aplicação atrás de um balanceador
Stateless (sem estado local)Aplicação que não guarda estado em memória entre requisições; pode ser replicada sem coordenação
Load Balancer (balanceador de carga)Componente que distribui requisições entre múltiplas instâncias da aplicação
API Gateway (gateway de API)Ponto de entrada único que centraliza autenticação, roteamento, rate limiting e logging
CDN (Content Delivery Network · Rede de Distribuição de Conteúdo)Rede de servidores geograficamente distribuídos que serve assets estáticos próximo ao usuário
Rate limiting (limitação de taxa)Controle do número de requisições aceitas por cliente em um intervalo de tempo
SSL termination (encerramento de SSL)Descriptografia do tráfego HTTPS no balanceador, aliviando as instâncias da aplicação
Health check (verificação de saúde)Endpoint que o balanceador consulta para saber se uma instância está saudável
Read replica (réplica de leitura)Cópia do banco sincronizada com a primária, usada exclusivamente para leitura
Sticky session (sessão fixada)Redirecionar sempre o mesmo usuário para a mesma instância; necessário em apps com estado local

Escala vertical

Aumentar a capacidade da máquina: mais CPU (Central Processing Unit · Unidade Central de Processamento), mais RAM (Random Access Memory · Memória de Acesso Aleatório), disco mais rápido.

Vantagens: zero mudança de código e zero complexidade de infraestrutura. Resolve a maioria dos gargalos de um sistema em crescimento.

Limite: existe um teto físico e financeiro. Uma máquina maior sempre custa mais do que duas máquinas menores com a mesma capacidade somada.

Quando usar: como primeiro passo de qualquer escala. Meça, identifique o gargalo, aumente o recurso correspondente. Passe para a escala horizontal quando o teto vertical for atingido ou quando o custo se tornar proibitivo.

Escala horizontal

Adicionar mais instâncias da aplicação e distribuir a carga entre elas.

Requisito central: a aplicação precisa ser stateless (sem estado local). Estado em memória (sessão, cache local, WebSocket com estado) impede a replicação, porque cada requisição precisa poder cair em qualquer instância e produzir o mesmo resultado.

Como tornar a aplicação stateless:

EstadoOnde mover
Sessão de usuárioRedis, banco de dados ou JWT (token autocontido)
Cache localRedis ou Memcached compartilhado
Arquivos temporáriosObject storage (S3, Blob Storage)
Filas em memóriaMessage broker (RabbitMQ, SQS, Kafka)

Com a aplicação stateless, adicionar instâncias tem efeito linear: duas instâncias dobram a capacidade, dez multiplicam por dez.

Balanceamento de carga

O Load Balancer (balanceador de carga) distribui as requisições entre as instâncias disponíveis, e é o ponto de entrada da escala horizontal.

Algoritmos de distribuição

AlgoritmoComo funcionaMelhor para
Round Robin (rotação sequencial)Distribui em ordem circular entre as instânciasRequisições com tempo de resposta similar
Least Connections (menor número de conexões)Direciona para a instância com menos conexões ativasRequisições com tempo de resposta variável
IP Hash (hash do IP do cliente)Sempre direciona o mesmo IP para a mesma instânciaApps que ainda têm estado local (sticky session)
Weighted (ponderado)Distribui proporcionalmente à capacidade de cada instânciaInstâncias com capacidades diferentes

Health checks

O balanceador consulta periodicamente um endpoint de cada instância (GET /health) e remove da rotação as que não respondem ou respondem com erro, até que se recuperem.

Load BalancerGET /health → 200 OK → instância saudável, recebe tráfego
Load BalancerGET /health → timeout → instância removida da rotação

SSL termination

O balanceador recebe o tráfego HTTPS (HyperText Transfer Protocol Secure · Protocolo Seguro de Transferência de Hipertexto), descriptografa e repassa HTTP (HyperText Transfer Protocol · Protocolo de Transferência de Hipertexto) simples para as instâncias internas. O gerenciamento de certificados fica centralizado no balanceador.

ClienteHTTPSLoad Balancer (SSL termination)HTTPInstâncias

API Gateway

O API Gateway é o ponto de entrada único para todos os serviços de uma API (Application Programming Interface · Interface de Programação de Aplicações). Ele centraliza responsabilidades que, sem ele, teriam de ser implementadas em cada serviço.

Responsabilidades centrais:

ResponsabilidadeO que faz
AutenticaçãoValida tokens antes de chegar aos serviços; serviços recebem identidade já verificada
Rate limitingLimita requisições por cliente, IP ou rota; protege os serviços de abuso
RoteamentoDireciona /orders/* para o serviço de pedidos, /users/* para o serviço de usuários
SSL terminationGerencia certificados HTTPS centralmente
Logging e observabilidadeRegistra todas as requisições em um único ponto; correlação de traces
Transformação de payloadAdapta formatos entre clientes e serviços quando necessário
ClienteAPI Gateway → autenticação → rate check → roteamento → Serviço A | Serviço B

O API Gateway é infraestrutura de entrada: faz pré-processamento e roteamento, e deixa a lógica de negócio para os serviços.

Ferramentas comuns: AWS API Gateway, Kong, Nginx, Traefik, Caddy.

Estratégias para escalar

Além de instâncias e balanceadores, existem camadas de escala que dispensam servidores novos:

CDN para assets estáticos: imagens, JS, CSS e fontes servidos a partir de nós geograficamente próximos ao usuário, sem carga nenhuma no servidor de aplicação.

Cache na borda: respostas de API guardadas no Redis ou Memcached, de modo que as requisições repetidas param antes de chegar ao banco.

RequisiçãoCache hit → resposta em < 1ms
RequisiçãoCache miss → banco → armazena → resposta

Read replicas: em sistemas com muito mais leitura do que escrita, as réplicas de leitura absorvem as queries SELECT sem tocar na instância primária.

Escrita → banco primário
Leitura → read replica 1 | read replica 2 | read replica N

Filas para absorver picos: em vez de processar operações lentas de forma síncrona, enfileire e processe em background. O servidor de aplicação responde rápido e o worker (processo que executa tarefas em segundo plano) absorve o pico no seu próprio ritmo.

Evitar engenharia excessiva

A maioria dos projetos nunca vai precisar de escala horizontal, balanceador dedicado ou várias read replicas. Investir nessa infraestrutura antes de ter o problema custa complexidade e não entrega nada em troca.

Sequência correta:

1. Monolito Modular + escala vertical
2. Otimizar queries e adicionar cache quando os dados indicarem
3. Adicionar load balancer e tornar stateless quando o tráfego exigir
4. Considerar read replicas quando leitura virar gargalo no banco
5. Microsserviços apenas quando limites de domínio ou times impuserem isolamento real

Cada etapa só faz sentido depois que a anterior se esgotou. Pular etapas aumenta a complexidade sem benefício proporcional.

Sinais de que é hora de escalar:

SinalAção correspondente
CPU ou memória consistentemente acima de 70%Escala vertical primeiro
Tempo de resposta crescendo com o volumeRevisar queries e adicionar cache
Máquina maior não resolve maisAvaliar escala horizontal
Um módulo tem tráfego radicalmente diferente dos demaisConsiderar extração cirúrgica

O que evitar no início:

  • Configurar load balancer antes de ter tráfego que justifique
  • Separar em microsserviços porque "vai crescer"
  • Montar Kubernetes para uma aplicação com 10 usuários simultâneos
  • Implementar CQRS (Command Query Responsibility Segregation · Separação de Responsabilidade entre Comando e Consulta) e event sourcing sem uma complexidade de leitura e escrita que justifique

Referência rápida

TécnicaQuando usarCusto de adoção
Escala verticalPrimeiro passo sempreNenhum (sem mudança de código)
Cache (Redis)Leitura frequente, escrita infrequenteBaixo (lib + Redis)
CDNAssets estáticos com usuários distribuídosBaixo (configuração de DNS)
Load BalancerTráfego que uma instância não absorveMédio (app deve ser stateless)
Read ReplicaLeitura virou gargalo no bancoMédio (configuração de banco)
API GatewayMúltiplos serviços ou autenticação centralizadaMédio (configuração e routing)
MicrosserviçosIsolamento real por domínio ou timeAlto (complexidade operacional)

DoDocs v3.7.0 · Desenvolvido por @thiagocajadev · Baseado no trabalho de pmndrs/docs · Poimandres.