Metodologia8 min

Modelagem de Performance: prevendo comportamento sob carga

Modelos de performance permitem prever como sistemas se comportarão antes de testar. Aprenda a criar modelos úteis e suas limitações.

Modelagem de performance é a arte de prever comportamento de sistemas sem precisar testá-los exaustivamente. Com modelos corretos, você pode responder perguntas como "quantos usuários aguenta?" sem executar testes caros.

Modelo é mapa, não território. Útil para navegar, perigoso para confiar cegamente.

Por Que Modelar

Custos de testes

Teste de carga real:
- Infraestrutura: $500-5000
- Tempo de preparação: 2-5 dias
- Execução: 1-4 horas
- Análise: 1-2 dias

Modelo matemático:
- Cálculo: minutos
- Custo: $0
- Iterações: ilimitadas

Quando modelar vale a pena

✓ Capacity planning antes de comprar infra
✓ Estimativas rápidas para stakeholders
✓ Comparar cenários hipotéticos
✓ Entender limites teóricos
✓ Validar intuição antes de testar

Fundamentos: Little's Law

A lei mais útil em modelagem de performance:

L = λ × W

L = número médio de itens no sistema
λ = taxa de chegada (throughput)
W = tempo médio no sistema (latência)

Exemplos práticos

1. Conexões de banco de dados

Throughput: 100 queries/s
Latência média: 50ms = 0.05s

Conexões ativas = 100 × 0.05 = 5 conexões

2. Capacidade de servidores

Cada servidor aguenta 100 conexões simultâneas
Latência por request: 200ms

Throughput por servidor = 100 / 0.2 = 500 req/s

3. Dimensionando infraestrutura

Meta: 10.000 req/s
Latência esperada: 100ms
Conexões simultâneas = 10.000 × 0.1 = 1.000

Se cada servidor aguenta 200 conexões:
Servidores necessários = 1.000 / 200 = 5

Teoria de Filas

Modelo M/M/1

Sistema com uma fila e um servidor:

λ = taxa de chegada
μ = taxa de serviço
ρ = λ/μ (utilização)

Para sistema estável: ρ < 1

Tempo médio no sistema:

W = 1 / (μ - λ)

Exemplo:

Chegadas: 80 req/s (λ)
Serviço: 100 req/s (μ)
Utilização: 80/100 = 80%

Tempo no sistema: 1/(100-80) = 50ms

Utilização vs Latência:

ρ = 50%:  W = 1/(100-50) = 20ms
ρ = 80%:  W = 1/(100-80) = 50ms
ρ = 90%:  W = 1/(100-90) = 100ms
ρ = 95%:  W = 1/(100-95) = 200ms
ρ = 99%:  W = 1/(100-99) = 1000ms

→ Latência explode perto de 100% utilização

Modelo M/M/c

Múltiplos servidores:

c = número de servidores

Para sistema estável: ρ = λ/(c×μ) < 1

Exemplo: Pool de conexões

Requisições: 200 req/s
Tempo por query: 20ms (μ = 50/s)

Com 1 conexão: 200/50 = 4 (instável!)
Com 4 conexões: 200/(4×50) = 1 (limite!)
Com 5 conexões: 200/(5×50) = 0.8 (estável)
Com 10 conexões: 200/(10×50) = 0.4 (margem)

Universal Scalability Law (USL)

Modelo que captura limites de escalabilidade:

C(N) = N / (1 + σ(N-1) + κN(N-1))

N = número de processadores/servidores
σ = coeficiente de contenção
κ = coeficiente de coerência
C(N) = capacidade relativa

Interpretação

σ (sigma): overhead de serialização
- Seções críticas, locks
- Quanto maior σ, pior escala

κ (kappa): overhead de coordenação
- Comunicação entre nós
- Quanto maior κ, pior escala

Perfis de escalabilidade

σ = 0, κ = 0: Linear (ideal)
N servidores = N× capacidade

σ > 0, κ = 0: Sublinear
Escala, mas com retornos decrescentes

σ > 0, κ > 0: Retrograde
Existe ponto máximo, depois piora

Exemplo prático:

Sistema com σ=0.1, κ=0.01

N=1:  C = 1.0
N=2:  C = 1.82 (1.82x)
N=4:  C = 3.08 (0.77x eficiência)
N=8:  C = 4.68 (0.58x eficiência)
N=16: C = 5.76 (0.36x eficiência)
N=32: C = 5.41 (pior que 16!)

→ Máximo ~22 servidores para esse sistema

Aplicando Modelos

Passo 1: Medir parâmetros

# Medir taxa de serviço (μ)
latencies = collect_latencies(sample_size=1000)
mu = 1 / mean(latencies)

# Medir taxa de chegada (λ)
arrivals = count_arrivals(window='1 minute')
lambda_ = arrivals / 60

# Calcular utilização
rho = lambda_ / mu

Passo 2: Validar modelo

# Calcular previsão
predicted_latency = 1 / (mu - lambda_)

# Comparar com observado
observed_latency = mean(latencies)

error = abs(predicted - observed) / observed
if error > 0.2:
    print("Modelo não se aplica bem")

Passo 3: Projetar

# Quanto aguenta com latência < 100ms?
target_latency = 0.1  # 100ms

# W = 1/(μ-λ) → λ = μ - 1/W
max_lambda = mu - (1 / target_latency)

print(f"Capacidade máxima: {max_lambda} req/s")

Limitações de Modelos

1. Distribuições assumidas

Modelos M/M/c assumem:
- Chegadas Poisson (exponenciais)
- Serviço exponencial

Realidade:
- Chegadas em rajadas
- Serviço com variância alta
- Dependências entre requests

2. Sistema fechado vs aberto

Sistema aberto: chegadas independentes
Sistema fechado: N usuários fixos

Modelo errado = previsão errada

3. Warm-up e estados

Modelo assume steady-state
Ignora:
- Cold start
- Cache warming
- JIT compilation
- Connection pooling

4. Dependências

Modelo de um componente ignora:
- Latência de rede
- Dependências externas
- Contenção em recursos compartilhados

Modelo Prático Simplificado

Quando modelos formais são complexos demais:

Regra dos 80%

Não opere acima de 80% de utilização
Margem para picos e variância

Fator de segurança

Capacidade necessária = Pico × 1.5

Se pico esperado = 1000 req/s
Provisione para 1500 req/s

Extrapolação linear com margem

Atual: 2 servidores, 500 req/s
Meta: 2000 req/s

Linear: 2000/500 × 2 = 8 servidores
Com margem 50%: 12 servidores
Com overhead de coordenação: 15 servidores

Ferramenta: Calculadora Rápida

def capacity_estimate(
    current_throughput: float,
    current_servers: int,
    target_throughput: float,
    efficiency: float = 0.7  # Assume 70% efficiency
) -> int:
    """
    Estima servidores necessários
    """
    throughput_per_server = current_throughput / current_servers
    ideal_servers = target_throughput / throughput_per_server
    real_servers = ideal_servers / efficiency

    return ceil(real_servers)

# Exemplo
servers = capacity_estimate(
    current_throughput=1000,
    current_servers=4,
    target_throughput=5000
)
print(f"Servidores necessários: {servers}")
# Output: Servidores necessários: 29

Conclusão

Modelos de performance são ferramentas poderosas, mas com limitações:

Use modelos para:

  1. Estimativas rápidas antes de testes
  2. Capacity planning inicial
  3. Identificar limites teóricos
  4. Comparar cenários hipotéticos

Não use modelos para:

  1. Decisões finais sem validação
  2. Sistemas complexos com muitas dependências
  3. Garantias de performance

Workflow recomendado:

1. Modele → Estimativa inicial
2. Teste → Validação do modelo
3. Ajuste → Refine parâmetros
4. Monitore → Validação contínua

Todos os modelos estão errados, mas alguns são úteis. — George Box

modelagemprevisãoLittle's Lawteoria de filas
Compartilhar:
Read in English

Quer entender os limites da sua plataforma?

Entre em contato para uma avaliação de performance.

Fale Conosco