Você quer medir como sua API se comporta exatamente a 500 requisições por segundo, não “o mais rápido que N threads conseguirem enviar”. A maioria das ferramentas de carga fixa a concorrência e deixa a taxa variar. O Vegeta faz o inverso: você define a taxa, e ele tenta enviar esse volume de requisições por segundo independentemente da velocidade de resposta do servidor. Isso importa quando você precisa validar throughput, latência e SLOs sob uma carga-alvo.
O que é Vegeta
Vegeta é uma ferramenta de teste de carga HTTP via linha de comando, escrita em Go. Também pode ser usada como biblioteca Go, mas este guia foca na CLI.
A ideia principal é simples:
você define uma taxa constante de requisições, e o Vegeta tenta manter esse ritmo durante todo o teste.
Exemplo: “envie 100 requisições por segundo por 30 segundos”. Se o servidor ficar lento, o Vegeta continua emitindo novas requisições conforme o cronograma, em vez de esperar as anteriores terminarem.
Isso cria um modelo de carga aberto, mais próximo de tráfego real: usuários chegam em seu próprio ritmo; eles não esperam seu endpoint lento terminar para que o próximo usuário apareça.
Carga baseada em taxa vs. baseada em concorrência
A diferença prática é esta:
- ferramentas baseadas em concorrência fixam usuários virtuais, threads ou workers;
- ferramentas baseadas em taxa fixam a quantidade de requisições por segundo.
Em um modelo baseado em concorrência, cada worker geralmente executa um loop:
enviar requisição -> aguardar resposta -> enviar próxima requisição
Se o servidor fica lento, o loop demora mais. Como consequência, a taxa real de requisições cai. A ferramenta “recua” sem você perceber.
Em um modelo baseado em taxa, como no Vegeta, você fixa a taxa de chegada. Se o servidor não acompanha, as requisições começam a se acumular, a latência sobe e os erros aparecem no relatório.
Use cada modelo para perguntas diferentes:
| Pergunta | Modelo mais adequado |
|---|---|
| Quantos usuários simultâneos minha API suporta? | Concorrência |
| O que acontece com 2.000 requisições por segundo? | Taxa |
| Em qual RPS a latência começa a degradar? | Taxa |
| Como duas builds se comportam sob a mesma carga? | Taxa |
Para uma visão mais ampla do ecossistema, veja as principais ferramentas de teste de carga de API.
Instalar Vegeta
Escolha a opção adequada para seu ambiente.
macOS com Homebrew
brew update && brew install vegeta
Outros gerenciadores de pacotes
# MacPorts
port install vegeta
# Arch Linux
pacman -S vegeta
# FreeBSD
pkg install vegeta
Compilar a partir do código-fonte
Com Go instalado:
git clone https://github.com/tsenart/vegeta
cd vegeta
make vegeta
Você também pode baixar um binário pré-compilado pela página de releases do GitHub.
Confirme a instalação:
vegeta --help
O pipeline principal
O Vegeta foi desenhado para funcionar bem com pipes Unix:
echo "GET http://localhost:8080/" | vegeta attack -duration=5s -rate=100 | vegeta report
Leia o comando da esquerda para a direita:
-
echoescreve um alvo HTTP: método e URL. -
vegeta attacklê o alvo pela entrada padrão e dispara100requisições por segundo por5s. -
vegeta reportlê os resultados e imprime um resumo.
Esse teste gera aproximadamente:
100 req/s * 5s = 500 requisições
A flag -rate aceita requisições por unidade de tempo:
-rate=100 # 100 requisições por segundo
-rate=100/1s # equivalente
-rate=50/500ms # 50 requisições a cada 500 ms
Use -rate=0 apenas quando quiser remover o limite e enviar o máximo possível. Isso muda o tipo de teste: deixa de ser uma carga constante controlada e vira um teste de throughput máximo.
Como ler o relatório
Um relatório de texto se parece com isto:
Requests [total, rate, throughput] 500, 100.20, 100.18
Duration [total, attack, wait] 4.991s, 4.990s, 1.2ms
Latencies [min, mean, 50, 90, 95, 99, max] 412us, 1.3ms, 1.1ms, 1.9ms, 2.4ms, 5.1ms, 12ms
Bytes In [total, mean] 128500, 257.00
Bytes Out [total, mean] 0, 0.00
Success [ratio] 100.00%
Status Codes [code:count] 200:500
Error Set:
Na prática, avalie nesta ordem:
-
Latencies
-
50: mediana. -
95: 95º percentil. -
99: cauda lenta. Se esse valor está alto, usuários reais sentirão o problema.
-
-
Success [ratio]
- Deve estar próximo de 100% para uma carga suportada.
-
Status Codes
- Verifique se há
5xx,429ou outros códigos inesperados.
- Verifique se há
-
Error Set
- Deve estar vazio em uma execução saudável.
Uma média boa não compensa um percentil 99 ruim. Em APIs, a cauda costuma ser onde os incidentes começam.
Salve os resultados antes de gerar relatórios
Para testes rápidos, enviar direto para vegeta report é suficiente. Para qualquer execução que você queira comparar, versionar ou anexar ao CI, salve o arquivo binário de resultados.
echo "GET http://localhost:8080/" | \
vegeta attack -duration=10s -rate=200 -output=results.bin
Depois gere relatórios a partir do arquivo.
Relatório de texto
vegeta report results.bin
JSON para dashboard ou automação
vegeta report -type=json results.bin > metrics.json
Histograma de latência
vegeta report -type='hist[0,2ms,5ms,10ms,25ms,100ms]' results.bin
O histograma mostra quantas requisições caíram em cada faixa de latência. É útil para identificar se a maioria das respostas está concentrada em uma faixa pequena ou se há dispersão significativa.
Criar um arquivo de alvos
APIs reais raramente são testadas com um único GET. Coloque seus endpoints em um arquivo e passe-o com -targets.
Crie targets.txt:
GET http://localhost:8080/api/users
POST http://localhost:8080/api/users
Content-Type: application/json
@./payload.json
GET http://localhost:8080/api/users/42
Crie o corpo da requisição em payload.json:
{ "name": "Ada", "role": "engineer" }
Execute:
vegeta attack -targets=targets.txt -rate=50 -duration=30s | vegeta report
Regras do formato:
- a primeira linha de cada alvo é
MÉTODO URL; - cabeçalhos vêm logo abaixo, no formato
Chave: Valor; - uma linha iniciada com
@referencia um arquivo usado como corpo da requisição; - uma linha em branco separa um alvo do próximo;
- linhas iniciadas com
#são comentários.
O Vegeta percorre os alvos em ordem e repete a lista até a duração terminar.
Adicionar autenticação
Para adicionar cabeçalhos globais, use -header.
Exemplo com Bearer Token:
vegeta attack -targets=targets.txt -rate=50 -duration=30s \
-header="Authorization: Bearer $TOKEN" | vegeta report
Você também pode adicionar outros cabeçalhos:
vegeta attack -targets=targets.txt -rate=50 -duration=30s \
-header="Authorization: Bearer $TOKEN" \
-header="X-Request-Source: load-test" | vegeta report
Usar formato JSON para alvos
Para geração programática, o Vegeta também aceita alvos em JSON. Cada linha é um objeto JSON.
Exemplo:
{"method": "GET", "url": "http://localhost:8080/api/users"}
{"method": "POST", "url": "http://localhost:8080/api/users", "header": {"Content-Type": ["application/json"]}, "body": "eyJuYW1lIjoiQWRhIn0="}
Execute com -format=json:
vegeta attack -format=json -targets=targets.json -rate=100 -duration=30s | vegeta report
O campo body deve estar em base64.
Esse formato funciona bem quando você gera alvos em tempo real. Para reduzir uso de memória em streams grandes, use -lazy.
generate-targets | vegeta attack -format=json -lazy -rate=100 -duration=30s | vegeta report
Gerar gráficos e comparar execuções
Um único número pode esconder degradações no meio do teste. Para visualizar latência ao longo do tempo, use vegeta plot.
vegeta attack -targets=targets.txt -rate=100 -duration=60s | \
vegeta plot > plot.html
Abra plot.html no navegador. Você verá uma série temporal da latência durante a execução.
Para comparar diferentes níveis de carga:
vegeta attack -rate=50 -duration=30s -targets=targets.txt -output=50qps.bin
vegeta attack -rate=100 -duration=30s -targets=targets.txt -output=100qps.bin
vegeta plot 50qps.bin 100qps.bin > compare.html
Em ambientes sem interface gráfica, exporte CSV:
vegeta encode -to=csv results.bin > results.csv
Encontrar o limite de capacidade
Um fluxo simples para encontrar o ponto de degradação:
for rate in 50 100 200 400 800; do
echo "Executando teste com ${rate} req/s"
vegeta attack \
-targets=targets.txt \
-rate=${rate} \
-duration=30s \
-output="results-${rate}.bin"
vegeta report "results-${rate}.bin" > "report-${rate}.txt"
done
Depois compare:
grep -E "Requests|Latencies|Success|Status Codes" report-*.txt
Procure o primeiro ponto em que:
- o percentil 95 ou 99 sobe de forma relevante;
- a taxa de sucesso cai;
- aparecem códigos
5xx,429ou timeouts; - o throughput fica abaixo da taxa solicitada.
Esse ponto indica que a API começou a não acompanhar a carga desejada.
Quando usar o Vegeta
Use Vegeta quando a pergunta for sobre taxa, latência e capacidade:
- medir throughput e latência em um RPS específico;
- descobrir em qual taxa a latência começa a subir;
- comparar duas builds sob carga idêntica;
- comparar duas configurações de infraestrutura;
- automatizar testes de carga em shell ou CI;
- gerar relatórios simples sem depender de GUI.
Ele é uma ferramenta focada. Envia requisições HTTP em uma taxa definida e mede como o servidor responde.
Ele não é ideal para:
- jornadas complexas com múltiplos passos e ramificações;
- simular navegação realista de usuários;
- validar regras de negócio;
- verificar schemas ou campos específicos no corpo da resposta.
Esse foco é positivo: mantém os testes repetíveis, scriptáveis e fáceis de interpretar.
Se estiver comparando alternativas, veja também os guias sobre teste de carga k6 e teste de carga JMeter. Para conceitos e métricas, comece pelo tutorial de teste de desempenho de API.
Onde o teste funcional entra
Teste de carga responde:
“A API é rápida o suficiente sob esta carga?”
Ele não responde:
“A API está retornando os dados corretos?”
Uma execução do Vegeta pode mostrar 100% de respostas 200 enquanto o endpoint retorna o usuário errado, um preço desatualizado ou um JSON inválido. Para uma ferramenta de carga, isso ainda pode parecer sucesso.
Correção exige outro tipo de validação:
- status esperado;
- cabeçalhos esperados;
- campos JSON;
- schema;
- regras de negócio;
- encadeamento entre requisições.
Isso é teste funcional, e deve acontecer antes ou junto dos testes de carga.
É aqui que o Apidog complementa o Vegeta. No Apidog, você cria cenários funcionais com asserções sobre status, cabeçalhos e campos JSON, encadeia requisições e usa dados externos. Depois, o Vegeta mede se os caminhos já validados continuam rápidos sob centenas ou milhares de requisições por segundo.
Executar testes funcionais no CI com Apidog CLI
O Apidog oferece uma CLI headless para executar cenários funcionais em pipelines.
Instale com Node:
npm install -g apidog-cli
Execute um cenário, pasta ou suíte salvo por ID:
apidog run --access-token "$APIDOG_ACCESS_TOKEN" \
-t <scenarioOrSuiteId> \
-e <environmentId> \
-r cli,html,junit
Parâmetros principais:
-
-t: ID do cenário, pasta ou suíte; -
-e: ID do ambiente; -
-r: formatos de relatório, comocli,html,jsonejunit.
A saída junit funciona bem em dashboards de CI.
Veja o tutorial da linha de comando da CLI do Apidog e o guia de pipeline CI/CD para um fluxo passo a passo.
Um pipeline saudável fica assim:
1. Executar testes funcionais
2. Bloquear o pipeline se asserções falharem
3. Executar Vegeta nos endpoints aprovados
4. Publicar relatórios de carga
Perguntas frequentes
Vegeta suporta requisições POST com corpo?
Sim. No arquivo de alvos HTTP, defina o método e a URL na primeira linha, adicione Content-Type e referencie o corpo com @./payload.json.
Exemplo:
POST http://localhost:8080/api/users
Content-Type: application/json
@./payload.json
No formato JSON, use method, url e body em base64.
O que -rate=0 faz?
Remove o limite de taxa e envia requisições tão rápido quanto workers e conexões permitirem.
Isso é útil para medir throughput máximo, mas não para um teste controlado de taxa constante. Para medições repetíveis, defina uma taxa explícita, como -rate=100.
Como leio os percentis de latência?
A linha Latencies mostra mínimo, média, mediana, percentis 90, 95, 99 e máximo.
Priorize:
-
95: comportamento lento para uma parte relevante dos usuários; -
99: cauda extrema; -
max: pior caso observado.
A média pode esconder problemas, então não use apenas mean.
Vegeta valida se minha API retorna dados corretos?
Não. Vegeta mede throughput, latência, códigos de status e erros de transporte. Ele não valida corpo da resposta, schema ou regras de negócio.
Combine Vegeta com uma ferramenta de teste funcional para validar correção antes de medir performance.
Como executo Vegeta em CI?
Como ele é um binário de linha de comando, basta adicionar uma etapa shell.
Exemplo:
vegeta attack \
-targets=targets.txt \
-rate=100 \
-duration=30s \
-output=results.bin
vegeta report results.bin
vegeta report -type=json results.bin > metrics.json
Publique results.bin, metrics.json e o relatório textual como artefatos do build.
Para evitar medir endpoints quebrados, rode primeiro um gate funcional, como a CLI do Apidog, e só depois execute a etapa de carga.
Top comments (0)