ApacheBench (ab): Como Fazer Teste de Carga de API no Terminal

Aprenda a fazer teste de carga de uma API com ApacheBench (ab): instale-o, execute testes com -n e -c, faça POST com -p e -T, e leia a saída de requisições/segundo e percentil.

INEZA Felin-Michel

INEZA Felin-Michel

6 julho 2026

ApacheBench (ab): Como Fazer Teste de Carga de API no Terminal

Apidog para empresas

Implantação local

SSO & RBAC

Conforme SOC 2

Explorar Apidog Enterprise

Você implantou um endpoint. Ele retorna o JSON correto no Postman. Mas você não tem ideia do que acontece quando 200 clientes o acessam de uma vez. Ele aguenta 500 requisições por segundo, ou a latência desmorona em 50? ApacheBench responde a essa pergunta em um único comando.

ApacheBench, invocado como ab, é uma ferramenta de linha de comando que dispara um número fixo de requisições HTTP para uma única URL e relata a vazão e a latência. Ele vem com o Apache HTTP Server e existe há décadas. É pequeno, rápido de executar e oferece uma leitura rápida de quanta carga um endpoint pode suportar.

Este guia aborda a instalação do ab, a execução de um teste básico, o teste de endpoints POST, a leitura da saída e o conhecimento de onde o ab deixa de ser a ferramenta certa. Cada comando aqui corresponde a uma flag documentada na referência oficial do Apache ab.

button

O que é ApacheBench e de onde ele vem

ab é um cliente de benchmarking empacotado com o Apache HTTP Server. O nome é uma abreviação de ApacheBench. Ele abre conexões para uma URL, envia requisições tão rápido quanto sua configuração de concorrência permite, cronometra cada resposta e imprime um resumo.

Ele mede uma coisa bem: quantas requisições por segundo um único endpoint pode servir e como o tempo de resposta é distribuído sob carga. Isso é vazão e latência para uma URL.

O que ele não faz é tão importante quanto. ab não verifica se o corpo da resposta está correto. Não valida um esquema nem verifica um campo. Não percorre um fluxo multi-etapas como login, depois buscar, depois atualizar. Ele atinge uma URL e conta. Mantenha esse escopo em mente e ab continuará útil. Espere mais e você ficará desapontado.

Se você quiser uma visão mais ampla da disciplina em que ab se encaixa, veja o que é teste de carga de API e por que o tempo de resposta da API é importante.

Instalando ab

ab vem empacotado com as utilidades do Apache. O nome do pacote difere por plataforma.

No Debian e Ubuntu, instale o pacote apache2-utils:

sudo apt-get update
sudo apt-get install -y apache2-utils

No CentOS, RHEL e Fedora, o pacote é httpd-tools:

# CentOS 7
sudo yum install -y httpd-tools

# Fedora e CentOS 8+
sudo dnf install -y httpd-tools

No macOS, ab já está presente porque o sistema vem com Apache. Verifique-o:

ab -V

Você deverá ver uma linha de versão como Version 2.3. Se o comando estiver ausente no macOS, instale-o através da fórmula Apache do Homebrew. Uma vez que ab -V imprimir uma versão, você estará pronto.

Executando um teste de carga básico

As duas flags que você usará sempre são -n e -c.

Aqui estão 1000 requisições, 50 por vez, contra um endpoint JSON:

ab -n 1000 -c 50 https://api.example.com/v1/users

Observe o caminho final. ab precisa de uma URL completa com um caminho. Se você apontá-lo para um host nu sem caminho, ele dará erro. Para a raiz, use uma barra final: https://api.example.com/.

Clientes reais reutilizam conexões TCP em vez de abrir uma nova a cada requisição. Adicione -k para habilitar o HTTP KeepAlive para que ab reutilize conexões dentro de uma sessão:

ab -n 1000 -c 50 -k https://api.example.com/v1/users

A execução com -k geralmente se aproxima mais de como um navegador ou um cliente de API bem comportado age, pois evita pagar o custo de configuração de conexão a cada requisição. Compare os dois números para ver quanto da sua latência é sobrecarga de conexão.

Você também pode limitar a execução por tempo em vez de contagem. -t define um número máximo de segundos e implica -n 50000 internamente, então o teste para no limite que for atingido primeiro:

ab -t 30 -c 50 -k https://api.example.com/v1/users

Isso é executado por até 30 segundos com concorrência 50. Útil quando você quer uma leitura de duração fixa em vez de uma contagem fixa.

Testando um endpoint POST

A maioria do trabalho de API não é GET. Para testar um POST, coloque o corpo da requisição em um arquivo e passe-o com -p. Você também precisa definir o tipo de conteúdo com -T, ou o servidor rejeitará o corpo.

Crie o payload:

cat > payload.json <<'EOF'
{"name": "Ada Lovelace", "email": "ada@example.com"}
EOF

Então envie-o:

ab -n 500 -c 25 -k \
  -p payload.json \
  -T application/json \
  https://api.example.com/v1/users

A flag -p nomeia o arquivo que contém o corpo do POST. A flag -T define o cabeçalho Content-Type. O tipo de conteúdo padrão é text/plain, que quase nunca é o que uma API JSON deseja, então defina -T application/json explicitamente.

Se seu endpoint precisar de autenticação ou outros cabeçalhos, adicione-os com -H. Repita a flag para cada cabeçalho:

ab -n 500 -c 25 -k \
  -p payload.json \
  -T application/json \
  -H "Authorization: Bearer SEU_TOKEN" \
  https://api.example.com/v1/users

Para uma revisão sobre como construir corpos de requisição JSON manualmente, veja como POSTar dados JSON com curl. O mesmo corpo funciona como um arquivo de payload ab.

Lendo a saída

Uma execução imprime um bloco de números. Aqui está um exemplo truncado:

Concurrency Level:      50
Time taken for tests:   4.212 seconds
Complete requests:      1000
Failed requests:        0
Non-2xx responses:      0
Requests per second:    237.42 [#/sec] (mean)
Time per request:       210.598 [ms] (mean)
Time per request:       4.212 [ms] (mean, across all concurrent requests)
Transfer rate:          142.31 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        5   18   9.4     16      64
Processing:    22  189  41.2    182     310
Waiting:       21  177  39.8    171     295
Total:         31  207  42.7    201     338

Percentage of the requests served within a certain time (ms)
  50%    201
  66%    221
  75%    236
  90%    268
  95%    291
  99%    324
 100%    338 (longest request)

Leia esses campos primeiro:

A tabela Percentage of the requests served within a certain time (ms) (Porcentagem das requisições servidas dentro de um certo tempo (ms)) é a parte mais útil. É uma quebra por percentil. A linha de 50% é sua mediana. As linhas de 95% e 99% mostram a cauda lenta. No exemplo, metade das requisições terminou em 201ms, mas 1% levou 324ms ou mais. A latência de cauda é onde os usuários reais são prejudicados, então observe os percentis 95 e 99 mais do que a média.

Quer os números brutos por requisição para um gráfico? Adicione -e results.csv para gravar um CSV de pares percentil-tempo, ou -g results.tsv para um arquivo amigável ao gnuplot.

Onde ab deixa de ser a ferramenta certa

ab é deliberadamente restrito. Seus limites merecem ser declarados claramente para que você não o utilize de forma inadequada.

Uma URL por execução. ab martela um único endpoint. Ele não consegue roteirizar uma sequência como autenticar, criar um recurso e depois lê-lo. Jornadas de usuários reais tocam muitos endpoints em ordem, e ab não tem conceito disso.

Sem verificações de correção. ab conta códigos de status e comprimentos de bytes. Ele não analisa seu JSON nem afirma que um campo é igual a um valor esperado. Uma resposta pode estar estruturalmente errada e ainda ser contada como sucesso. Números de carga não substituem uma suíte de testes aprovada.

Tratamento HTTP desatualizado. A documentação oficial afirma que ab não implementa HTTP/1.x completamente e aceita apenas algumas formas esperadas de respostas. Ele não tem suporte a HTTP/2. Para servidores que se comportam de forma diferente sob HTTP/2, ab não refletirá isso.

Carga de máquina única. ab é executado de uma única máquina e um único processo. A partir de uma certa concorrência, você mede os limites do seu próprio cliente em vez dos do servidor. A documentação até avisa que a própria análise do ab pode aparecer como um gargalo em perfis.

Nada disso torna o ab ruim. Isso o torna uma ferramenta específica: uma sonda de vazão rápida para um único endpoint. Quando você precisar de fluxos roteirizados, carga distribuída ou HTTP/2, procure algo feito para isso. JMeter lida com cenários multi-etapas e execuções distribuídas, e há um apanhado mais amplo de ferramentas de teste de carga se você estiver comparando opções.

Onde o teste funcional se encaixa

Vazão é um eixo. Correção é outro, e ab não o toca. Antes de testar a carga de um endpoint, você precisa saber se ele retorna os dados corretos com a forma correta em condições normais. Isso é teste funcional e de contrato, e é um trabalho diferente.

É aqui que uma plataforma de API completa ganha seu lugar ao lado do ab. O Apidog permite que você construa cenários de teste com asserções visuais, encadeie requisições em fluxos multi-etapas e valide respostas contra seu esquema, coisas que o ab não pode fazer por design. Você salva esses cenários uma vez e os executa em qualquer lugar.

Para integração contínua, a CLI do Apidog executa seus cenários salvos sem interface gráfica. Instale-o com Node:

npm install -g apidog-cli

Em seguida, execute um cenário ou suíte salva contra um ambiente escolhido, emitindo relatórios que sua CI pode arquivar:

apidog run \
  --access-token "$APIDOG_ACCESS_TOKEN" \
  -t <scenarioOrSuiteId> \
  -e <environmentId> \
  -r cli,html,junit

A flag -t direciona um cenário, pasta ou suíte salvo pelo ID. A flag -e seleciona o ambiente. A flag -r escolhe um ou mais relatores entre cli, html, json e junit. Para execuções orientadas por dados, adicione -d (ou --iteration-data) com um caminho de arquivo de dados ou ID de dados de teste. A CLI é headless e executa cenários salvos, então ela se encaixa em qualquer etapa de CI que possa executar Node. Não é um remetente de requisições nem um gerador de carga, ela executa os testes funcionais que o ab nunca foi feito para executar.

Uma configuração saudável usa ambos. Execute cenários Apidog para provar que o endpoint está correto. Execute ab para provar que ele é rápido o suficiente. Para o lado da correção, veja o guia de teste de desempenho do Apidog e o tutorial geral de teste de desempenho de API.

FAQ

ApacheBench é apenas para servidores Apache?

Não. Apesar do nome, ab envia requisições HTTP e HTTPS simples para qualquer servidor. Funciona contra Nginx, Node, Go, Python ou qualquer host que fale HTTP. A ligação com Apache é apenas que a ferramenta vem com o Apache HTTP Server.

Qual concorrência e contagem de requisições devo usar?

Comece baixo e aumente. Tente -n 1000 -c 10, depois aumente -c para 25, 50, 100 e observe onde as requisições por segundo param de aumentar e as requisições falhas começam a aparecer. Esse ponto de inflexão é aproximadamente onde o endpoint satura. Combine sua concorrência de pico com o tráfego real esperado, em vez de escolher um número redondo grande.

Por que minhas requisições falhas são altas quando a API funciona bem?

ab marca uma requisição como falha se o comprimento da resposta variar entre as requisições, o que é normal para JSON dinâmico. Adicione a flag -l para parar de contar diferenças de comprimento como falhas. Em seguida, verifique a linha "Non-2xx responses" para ver se há erros reais subjacentes.

ab pode testar um endpoint que precisa de um token de login?

Sim, se você já tiver um token. Passe-o com -H "Authorization: Bearer SEU_TOKEN". O que ab não pode fazer é logar primeiro para obter um token fresco e depois usá-lo. Esse é um fluxo multi-etapas, e você precisa de uma ferramenta baseada em cenários como Apidog para isso.

ab suporta HTTP/2?

Não. ab fala HTTP/1.x e, de acordo com a documentação oficial, nem mesmo o implementa totalmente. Se o comportamento do seu servidor sob HTTP/2 for importante, use uma ferramenta de carga com suporte a HTTP/2.

Pratique o design de API no Apidog

Descubra uma forma mais fácil de construir e usar APIs