Como usar ab e wrk para testes de carga simples em APIs
1. Introdução aos Testes de Carga com Ferramentas de Linha de Comando
Testar a capacidade de uma API antes de colocá-la em produção é uma prática essencial para garantir que o sistema suporte o volume esperado de requisições sem degradar a experiência do usuário. Ferramentas de linha de comando como Apache Bench (ab) e wrk oferecem uma abordagem direta e eficiente para realizar testes de carga sem a complexidade de soluções corporativas.
O Apache Bench, parte do ecossistema Apache HTTP Server, é uma ferramenta madura e amplamente disponível que realiza testes de throughput básicos. Já o wrk, desenvolvido em C com suporte a scripts Lua, oferece maior controle sobre cenários de teste e métricas mais detalhadas, como percentis de latência.
Quando usar cada ferramenta:
- ab: Ideal para testes rápidos de validação, ambientes com restrições de instalação e cenários onde apenas requisições GET simples são necessárias.
- wrk: Recomendado para testes mais realistas, com múltiplas threads, requisições POST com payloads e necessidade de métricas estatísticas avançadas.
Ambas as ferramentas são gratuitas, open-source e funcionam em Linux, macOS e Windows, tornando-as acessíveis para qualquer desenvolvedor.
2. Instalação e Configuração Inicial
Instalando o Apache Bench
Linux (Debian/Ubuntu):
sudo apt update
sudo apt install apache2-utils
macOS (via Homebrew):
brew install apr apr-util
# O ab já vem instalado no macOS, mas pode ser atualizado via Xcode Command Line Tools
Windows:
# Baixe o Apache Lounge: https://www.apachelounge.com/download/
# Extraia e adicione o diretório bin ao PATH do sistema
Instalando o wrk
Linux (Ubuntu/Debian):
sudo apt install build-essential libssl-dev git -y
git clone https://github.com/wg/wrk.git
cd wrk
make
sudo cp wrk /usr/local/bin/
macOS:
brew install wrk
Windows (via Chocolatey):
choco install wrk
Verificando as versões
ab -V
wrk --version
Ambas as ferramentas não exigem dependências complexas além das bibliotecas SSL para suporte HTTPS.
3. Testes Básicos com Apache Bench (ab)
Sintaxe fundamental
ab -n 1000 -c 10 https://api.exemplo.com/v1/usuarios
Onde:
- -n: número total de requisições
- -c: número de requisições concorrentes
- A URL deve terminar com / para endpoints raiz
Interpretando resultados
ab -n 500 -c 20 http://localhost:3000/api/health
Saída típica:
Concurrency Level: 20
Time taken for tests: 2.345 seconds
Complete requests: 500
Failed requests: 0
Requests per second: 213.22 [#/sec] (mean)
Time per request: 93.80 [ms] (mean)
Transfer rate: 45.67 [Kbytes/sec] received
Métricas chave:
- Requests per second: throughput do servidor
- Time per request: latência média por requisição
- Failed requests: indica problemas de conectividade ou timeout
Exemplo com cabeçalhos customizados
ab -n 200 -c 10 -H "Authorization: Bearer token123" \
-H "Content-Type: application/json" \
http://localhost:3000/api/protected
4. Aprofundando com wrk: Scripts e Métricas Avançadas
Comando básico
wrk -t4 -c100 -d30s http://localhost:3000/api/health
Onde:
- -t: número de threads
- -c: número de conexões simultâneas
- -d: duração do teste (ex: 30s, 2m)
Criando scripts Lua para simular comportamentos
Arquivo teste-post.lua:
wrk.method = "POST"
wrk.body = '{"email": "teste@exemplo.com", "senha": "123456"}'
wrk.headers["Content-Type"] = "application/json"
Executando:
wrk -t2 -c20 -d15s -s teste-post.lua http://localhost:3000/api/login
Analisando latência e percentis
wrk -t4 -c50 -d30s --latency http://localhost:3000/api/usuarios
Saída com percentis:
Thread Stats Avg Stdev Max +/- Stdev
Latency 45.23ms 12.34ms 345.67ms 78.50%
Req/Sec 1.23k 234.56 2.10k 68.45%
Latency Distribution (HdrHistogram)
50.000% 42.00ms
75.000% 51.00ms
90.000% 63.00ms
99.000% 98.00ms
Os percentis p50, p90 e p99 são cruciais para entender a experiência real do usuário, especialmente em sistemas com variação de carga.
5. Comparando Resultados e Interpretando Métricas Chave
Diferenças fundamentais
| Característica | Apache Bench (ab) | wrk |
|---|---|---|
| Concorrência | Baseada em processos | Baseada em threads |
| Suporte a scripts | Limitado | Completo (Lua) |
| Percentis de latência | Não | Sim (HdrHistogram) |
| Requisições POST | Sim, mas limitado | Sim, com scripts |
Identificando gargalos
- CPU alto: latência aumenta linearmente com concorrência
- I/O de rede: throughput estagna mesmo aumentando conexões
- Banco de dados: erros de timeout ou conexão recusada
Boas práticas para resultados confiáveis
- Warm-up: execute 10-20% das requisições antes de medir
- Cooldown: aguarde 5-10 segundos entre testes
- Múltiplas execuções: repita o teste 3-5 vezes e calcule a média
- Ambiente isolado: evite executar outros processos durante o teste
# Exemplo de warm-up com ab
ab -n 100 -c 10 http://localhost:3000/api/health > /dev/null
sleep 2
ab -n 1000 -c 50 http://localhost:3000/api/health
6. Cenários Práticos de Teste em APIs REST
Testando endpoints POST com payload
Arquivo criar-usuario.lua:
wrk.method = "POST"
wrk.body = '{"nome": "João Silva", "email": "joao@exemplo.com"}'
wrk.headers["Content-Type"] = "application/json"
wrk -t2 -c10 -d20s -s criar-usuario.lua http://localhost:3000/api/usuarios
Simulando múltiplos endpoints
Script multiplos-endpoints.lua:
local contador = 0
request = function()
contador = contador + 1
if contador % 2 == 0 then
return wrk.format("GET", "/api/health")
else
return wrk.format("POST", "/api/login",
{["Content-Type"] = "application/json"},
'{"usuario":"admin","senha":"123"}')
end
end
wrk -t4 -c20 -d30s -s multiplos-endpoints.lua http://localhost:3000
Integrando em pipelines CI/CD
Exemplo com GitHub Actions:
name: Teste de Carga
on: [push]
jobs:
load-test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Instalar wrk
run: |
sudo apt update
sudo apt install build-essential libssl-dev -y
git clone https://github.com/wg/wrk.git
cd wrk && make && sudo cp wrk /usr/local/bin/
- name: Executar teste
run: |
wrk -t2 -c10 -d10s http://${{ secrets.API_URL }}/health
7. Limitações e Alternativas para Testes Mais Complexos
Quando ab e wrk não são suficientes
- Testes distribuídos: cenários que exigem múltiplas máquinas gerando carga
- Cenários de usuário complexos: navegação com sessões e cookies
- Monitoramento em tempo real: dashboards com métricas contínuas
Ferramentas complementares
- Vegeta: teste de carga com saída formatada em JSON, ideal para automação
- Hey: similar ao wrk, mas com foco em simplicidade e suporte nativo a HTTP/2
- k6: ferramenta moderna com scripts em JavaScript e integração com Grafana
Próximos passos
Para testes contínuos em produção, considere:
1. Implementar health checks com métricas exportadas para Prometheus
2. Usar dashboards Grafana para visualizar latência e throughput
3. Configurar alertas automáticos quando p99 ultrapassar thresholds definidos
Referências
- Documentação oficial do Apache Bench (ab) — Guia completo com todas as opções de linha de comando e interpretação de resultados
- Repositório oficial do wrk no GitHub — Código fonte, documentação e exemplos de scripts Lua para testes avançados
- Tutorial de wrk no DigitalOcean — Guia prático de instalação e uso do wrk em servidores Ubuntu
- Comparativo entre ferramentas de teste de carga (ab vs wrk vs vegeta) — Análise detalhada das diferenças e melhores casos de uso para cada ferramenta
- Documentação do k6 para testes de carga modernos — Alternativa avançada com scripts JavaScript e integração CI/CD
- Guia de boas práticas para testes de carga em APIs REST — Estratégias para evitar resultados falsos e interpretar métricas corretamente