"O sistema está lento, vamos adicionar mais instâncias." Uma semana depois: "Continua lento, mas agora custa o dobro." Escalar sem entender o gargalo é jogar dinheiro fora. Este artigo ensina a escalar certo — no momento certo, da forma certa.
Escalar é a última opção, não a primeira. Otimizar é mais barato.
Quando Escalar
Sinais de que precisa escalar
Indicadores legítimos:
- Recursos em >80% de utilização sustentada
- Otimizações já foram feitas
- Crescimento de carga é inevitável
- Headroom para picos é insuficiente
Indicadores de que NÃO precisa escalar:
- Latência alta mas recursos ociosos
- Performance degradou após mudança de código
- Gargalo em componente específico
- Problema intermitente
Perguntas antes de escalar
1. O gargalo é de capacidade ou código?
→ Profiling/tracing identificou onde está o tempo?
2. Otimizações óbvias já foram feitas?
→ Índices de DB? Cache? Connection pooling?
3. Escalar vai resolver ou mover o gargalo?
→ Mais app servers não ajudam se DB é gargalo
4. Qual o custo de escalar vs otimizar?
→ 2 instâncias extras = $X/mês
→ 1 semana de otimização = $Y único
5. Escala horizontal ou vertical?
→ Depende do tipo de carga e arquitetura
Estratégias de Escala
Escala Vertical (Scale Up)
O que é:
Aumentar recursos de uma instância
(CPU, memória, disco)
Quando usar:
- Aplicação não é distribuída
- Overhead de coordenação é alto
- Limite ainda não atingido
- Simples de implementar
Vantagens:
- Não requer mudança de código
- Sem complexidade de distribuição
- Latência entre componentes mínima
Desvantagens:
- Limite físico (maior instância disponível)
- Custo cresce não-linear
- Único ponto de falha
Escala Horizontal (Scale Out)
O que é:
Adicionar mais instâncias
com load balancer distribuindo carga
Quando usar:
- Aplicação é stateless
- Carga é paralelizável
- Precisa de alta disponibilidade
- Limite vertical já atingido
Vantagens:
- Teoricamente ilimitada
- Custo linear
- Redundância natural
Desvantagens:
- Requer arquitetura adequada
- Complexidade de coordenação
- State management é desafio
Escala de Componentes
Não escale tudo igual:
Identificar gargalo:
- App servers: CPU-bound
- Database: I/O-bound
- Cache: Memory-bound
Escalar seletivamente:
Se gargalo = App:
→ Adicionar mais pods/instâncias
Se gargalo = DB reads:
→ Adicionar read replicas
Se gargalo = DB writes:
→ Sharding ou banco diferente
Se gargalo = Cache:
→ Aumentar memória ou cluster
O Custo de Escalar Errado
Cenário 1: Escalar quando deveria otimizar
Problema: Latência alta (2s)
Ação: Dobrar número de servidores
Custo: +$5K/mês
Resultado:
- Latência ainda 2s
- Gargalo era query sem índice
- Solução correta: CREATE INDEX (5 min, $0)
Desperdício: $5K/mês × 12 = $60K/ano
Cenário 2: Escalar o componente errado
Problema: Checkout lento sob carga
Ação: Triplicar servidores de aplicação
Custo: +$10K/mês
Resultado:
- Checkout ainda lento
- Gargalo era connection pool do DB
- DB não escala com mais app servers
Solução correta:
- Aumentar connection pool
- Ou adicionar read replica para queries
Cenário 3: Escalar antes de precisar
Problema: "Black Friday vem aí"
Ação: Provisionar 10x a capacidade atual
Custo: +$50K/mês
Resultado:
- Black Friday teve 3x de pico (não 10x)
- Maioria dos recursos ociosos
- Dinheiro desperdiçado
Solução correta:
- Stress test para validar necessidade real
- Escalar para margem de segurança (20-50%)
- Autoscaling para picos
Capacity Planning
Modelo de projeção
Dados históricos:
- Crescimento mensal: 15%
- Pico atual: 1000 req/s
- Capacidade atual: 1500 req/s
Projeção:
Mês 3: 1520 req/s (atinge limite)
Mês 6: 2313 req/s (50% acima do limite)
Ação:
Planejar escala para mês 2
Validar com stress test em mês 1
Margem de segurança
Regra prática:
Capacidade = Pico esperado × 1.5
Exemplo:
Pico Black Friday esperado: 5000 req/s
Capacidade necessária: 7500 req/s
Capacidade atual: 3000 req/s
Gap: 4500 req/s
Plano:
- Opção A: Escalar para 8000 req/s (+$X)
- Opção B: Otimizar para 5000 req/s (X sprints)
- Opção C: Combinação
Arquitetura para Escala
Princípios
Stateless:
- Sessão em Redis, não em memória
- Arquivos em S3, não no disco local
- Permite escalar horizontalmente
Loose Coupling:
- Comunicação assíncrona onde possível
- Filas para absorver picos
- Falha de um não derruba outros
Database:
- Read replicas para leitura
- Connection pooling adequado
- Índices para queries críticas
Cache:
- Cache agressivo de dados estáticos
- Invalidação bem definida
- Cache em múltiplas camadas
Padrões de escala
Load Balancer:
- Distribui carga entre instâncias
- Health checks para remover unhealthy
- Sticky sessions se necessário (evitar)
Auto-scaling:
- Escala baseada em métricas
- CPU, memória, queue depth, custom
- Scale-in policy para economia
Queue-based:
- Absorve picos de carga
- Permite processar no ritmo possível
- Desacopla produtores de consumidores
CDN:
- Offload de assets estáticos
- Cache de edge para latência
- DDoS protection
Autoscaling
Quando usar
Bom para:
- Carga variável e previsível
- Aplicação stateless
- Tempo de startup rápido
- Custo importa
Ruim para:
- Carga sempre constante
- Startup lento (>5 min)
- Estado local necessário
Configuração típica
# Kubernetes HPA
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: api-scaler
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: api
minReplicas: 3
maxReplicas: 20
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70
- type: Pods
pods:
metric:
name: requests_per_second
target:
type: AverageValue
averageValue: 1000
behavior:
scaleUp:
stabilizationWindowSeconds: 60
scaleDown:
stabilizationWindowSeconds: 300
Métricas de autoscaling
Métricas comuns:
- CPU utilization (mais comum)
- Memory utilization
- Request rate (req/s)
- Queue depth
- Custom metrics (latência, etc)
Cuidados:
- Scale-up rápido para reagir a picos
- Scale-down lento para evitar flapping
- Margem para cold start
- Limites min/max sensatos
Validando Escala
Antes de produção
1. Stress test no novo tamanho:
- Valida que realmente resolve
- Identifica novo gargalo
2. Chaos testing:
- Falhar uma instância
- Validar que outras absorvem
3. Custo validado:
- Projeção de custo mensal
- Aprovação de budget
Após produção
1. Monitorar utilização:
- Recursos estão sendo usados?
- Ou estão ociosos?
2. Revisar periodicamente:
- Capacidade ainda faz sentido?
- Pode reduzir sem risco?
3. Ajustar autoscaling:
- Thresholds adequados?
- Tempo de reação ok?
Conclusão
Escalar certo significa:
- Identificar gargalo primeiro - escalar o componente certo
- Otimizar antes de escalar - mais barato e sustentável
- Escolher estratégia correta - vertical, horizontal, ou componente
- Planejar com dados - não com medo
- Validar antes de produção - stress test confirma
- Revisar após produção - ajustar ou reduzir
A pergunta não é "quanto escalar", mas "por que escalar" e "escalar o quê".
Mais hardware não conserta código ruim. Conserta apenas a conta de cloud.
Este artigo faz parte da série sobre a metodologia OCTOPUS de Performance Engineering.