DEV Community

Cover image for Vegeta: Tutorial de Pruebas de Carga HTTP a Tasa Constante
Roobia
Roobia

Posted on • Originally published at apidog.com

Vegeta: Tutorial de Pruebas de Carga HTTP a Tasa Constante

Quieres saber cómo se comporta tu API a exactamente 500 solicitudes por segundo, no “tan rápido como N hilos puedan bombardearla”. La mayoría de las herramientas de carga fijan la concurrencia y dejan que la tasa de solicitudes fluctúe. Vegeta hace lo contrario: tú estableces la tasa y envía esa cantidad de solicitudes por segundo, independientemente de cómo responda el servidor. Esa diferencia importa cuando necesitas medir rendimiento bajo una carga objetivo, validar latencia para un SLO y detectar cuándo la demanda supera la capacidad.

Prueba Apidog hoy

¿Qué es Vegeta?

Vegeta es una herramienta de prueba de carga HTTP de línea de comandos escrita en Go. También se puede usar como biblioteca de Go, pero este tutorial se centra en la CLI.

La idea central es una tasa de solicitudes constante:

# 100 solicitudes por segundo durante 30 segundos
vegeta attack -rate=100 -duration=30s
Enter fullscreen mode Exit fullscreen mode

Si el servidor se ralentiza, Vegeta sigue emitiendo nuevas solicitudes según lo programado en lugar de esperar a que las anteriores terminen. Ese diseño implementa un modelo abierto de carga: el tráfico llega a su propio ritmo, como ocurre en producción.

Carga basada en tasa vs. carga basada en concurrencia

La diferencia clave está en qué variable controlas.

Una herramienta basada en concurrencia usa un modelo cerrado: defines un número fijo de hilos, usuarios virtuales o workers. Cada uno ejecuta un ciclo solicitud-respuesta. Si el servidor se vuelve lento, el ciclo también se ralentiza, así que la tasa real de solicitudes baja. Eso puede ocultar la acumulación que verías en producción.

Una herramienta basada en tasa como Vegeta usa un modelo abierto: defines la tasa de llegada. Si el servidor no puede seguir el ritmo, las solicitudes se acumulan, la latencia sube y el informe lo refleja.

Usa cada modelo para preguntas distintas:

  • Concurrencia: “¿cuántos usuarios simultáneos puedo soportar?”
  • Tasa: “¿qué pasa a 2.000 solicitudes por segundo?”

Vegeta pertenece al segundo grupo. Para un mapa más amplio de opciones, consulta las mejores herramientas de prueba de carga de API.

Instalar Vegeta

Elige el método que encaje con tu entorno.

En macOS con Homebrew:

brew update && brew install vegeta
Enter fullscreen mode Exit fullscreen mode

Otros gestores de paquetes:

# MacPorts
port install vegeta

# Arch Linux
pacman -S vegeta

# FreeBSD
pkg install vegeta
Enter fullscreen mode Exit fullscreen mode

Desde el código fuente con Go instalado:

git clone https://github.com/tsenart/vegeta
cd vegeta
make vegeta
Enter fullscreen mode Exit fullscreen mode

También puedes descargar un binario precompilado desde la página de releases de GitHub.

Verifica la instalación:

vegeta --help
Enter fullscreen mode Exit fullscreen mode

Ejecutar tu primera prueba

Vegeta se integra bien con pipelines Unix. Un objetivo entra, un ataque se ejecuta y un informe sale.

Ejemplo mínimo:

echo "GET http://localhost:8080/" | vegeta attack -duration=5s -rate=100 | vegeta report
Enter fullscreen mode Exit fullscreen mode

Qué ocurre en esa línea:

  1. echo escribe un objetivo HTTP: método y URL.
  2. vegeta attack lee el objetivo desde stdin.
  3. Vegeta lanza 100 solicitudes por segundo durante 5s.
  4. vegeta report lee los resultados binarios e imprime un resumen.

Eso produce unas 500 solicitudes en total.

La opción -rate acepta solicitudes por unidad de tiempo:

-rate=100       # 100 solicitudes por segundo
-rate=100/1s    # equivalente
-rate=50/500ms  # 50 solicitudes cada 500 ms
Enter fullscreen mode Exit fullscreen mode

Evita -rate=0 salvo que quieras una prueba sin límite. En ese modo, Vegeta envía tan rápido como pueda, que es una prueba distinta a una carga controlada.

Interpretar el informe

Un informe de texto puede verse así:

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:
Enter fullscreen mode Exit fullscreen mode

Lee el informe en este orden:

  1. Latencies

    • 50: mediana.
    • 95 y 99: cola de latencia.
    • Si el percentil 99 es alto, algunos usuarios están teniendo una mala experiencia aunque la media parezca saludable.
  2. Success [ratio]

    • Un 100.00% indica que todas las respuestas fueron exitosas según Vegeta.
  3. Status Codes

    • 200:500 significa 500 respuestas HTTP 200.
    • Códigos 5xx indican fallos del servidor.
    • Códigos 4xx pueden indicar problemas en la prueba, autenticación o datos.
  4. Error Set

    • Debe estar vacío para una ejecución limpia.
    • Si contiene errores, revisa timeouts, DNS, conexiones rechazadas o fallos TLS.

Guardar resultados y generar informes

Enviar directamente a report sirve para una comprobación rápida. Para una prueba que vayas a comparar o archivar, guarda primero los resultados brutos.

echo "GET http://localhost:8080/" | \
  vegeta attack -duration=10s -rate=200 -output=results.bin
Enter fullscreen mode Exit fullscreen mode

Genera un informe de texto:

vegeta report results.bin
Enter fullscreen mode Exit fullscreen mode

Genera JSON estructurado para dashboards, scripts o comparaciones entre ejecuciones:

vegeta report -type=json results.bin > metrics.json
Enter fullscreen mode Exit fullscreen mode

Genera un histograma de latencia con rangos personalizados:

vegeta report -type='hist[0,2ms,5ms,10ms,25ms,100ms]' results.bin
Enter fullscreen mode Exit fullscreen mode

El histograma cuenta cuántas solicitudes cayeron en cada rango. Úsalo para ver si la latencia está concentrada o dispersa.

Crear un archivo de objetivos

Las APIs reales suelen necesitar headers, cuerpos y varios endpoints. Para eso, usa un archivo de objetivos con -targets.

Crea 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
Enter fullscreen mode Exit fullscreen mode

Reglas del formato:

  • La primera línea de cada objetivo es MÉTODO URL.
  • Los headers van debajo, uno por línea: Clave: Valor.
  • Una línea que empieza con @ referencia un archivo cuyo contenido se envía como body.
  • Una línea en blanco separa objetivos.
  • Las líneas que empiezan con # son comentarios.

Crea el cuerpo JSON en payload.json:

{ "name": "Ada", "role": "engineer" }
Enter fullscreen mode Exit fullscreen mode

Ejecuta la prueba:

vegeta attack -targets=targets.txt -rate=50 -duration=30s | vegeta report
Enter fullscreen mode Exit fullscreen mode

Vegeta recorre los objetivos en orden y repite el ciclo hasta que termina la duración.

Para headers globales, usa -header. Es útil para autenticación:

vegeta attack -targets=targets.txt -rate=50 -duration=30s \
  -header="Authorization: Bearer $TOKEN" | vegeta report
Enter fullscreen mode Exit fullscreen mode

Usar objetivos en formato JSON

Para ejecuciones programáticas o de alto volumen, Vegeta también acepta un formato JSON línea por línea.

Ejemplo:

{"method": "GET", "url": "http://localhost:8080/api/users"}
{"method": "POST", "url": "http://localhost:8080/api/users", "header": {"Content-Type": ["application/json"]}, "body": "eyJuYW1lIjoiQWRhIn0="}
Enter fullscreen mode Exit fullscreen mode

Ejecuta con -format=json:

vegeta attack -format=json -targets=targets.json -rate=100 -duration=30s | vegeta report
Enter fullscreen mode Exit fullscreen mode

El campo body debe estar codificado en base64. Este formato funciona bien cuando generas objetivos dinámicamente desde otro proceso.

Para generar objetivos sobre la marcha y optimizar memoria, usa -lazy:

generate-targets | vegeta attack -format=json -lazy -rate=100 -duration=30s | vegeta report
Enter fullscreen mode Exit fullscreen mode

Graficar resultados

Un promedio puede ocultar tendencias. Si la latencia se degrada a mitad de la ejecución, necesitas ver la serie temporal.

Genera un gráfico HTML:

vegeta attack -targets=targets.txt -rate=100 -duration=60s | \
  vegeta plot > plot.html
Enter fullscreen mode Exit fullscreen mode

Abre plot.html en el navegador. Verás la latencia a lo largo del tiempo, lo que permite detectar picos, degradación progresiva o inestabilidad.

También puedes comparar varias ejecuciones:

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
Enter fullscreen mode Exit fullscreen mode

Para entornos sin interfaz gráfica, exporta CSV:

vegeta encode -to=csv results.bin > results.csv
Enter fullscreen mode Exit fullscreen mode

Encontrar la capacidad aproximada de un endpoint

Un flujo práctico consiste en ejecutar la misma prueba con tasas crecientes y comparar latencia, errores y throughput.

Ejemplo:

for rate in 50 100 200 400 800; do
  vegeta attack \
    -targets=targets.txt \
    -rate="$rate" \
    -duration=30s \
    -output="results-${rate}qps.bin"

  vegeta report -type=json "results-${rate}qps.bin" > "metrics-${rate}qps.json"
done
Enter fullscreen mode Exit fullscreen mode

Después revisa:

  • Cuándo aparece el primer error.
  • Cuándo suben los percentiles 95 y 99.
  • Si el throughput deja de crecer aunque suba la tasa.
  • Si aparecen códigos 429, 500, 502, 503 o timeouts.

Ese punto suele indicar que estás cerca del límite práctico para esa configuración.

Cuándo usar Vegeta

Usa Vegeta cuando la pregunta sea sobre tasa y capacidad:

  • Necesitas rendimiento y latencia a una tasa específica de solicitudes por segundo.
  • Quieres encontrar la tasa a la que la latencia o los errores empiezan a aumentar.
  • Estás comparando dos versiones o dos configuraciones de infraestructura con una carga idéntica.
  • Quieres una herramienta scriptable para shell y CI.
  • Necesitas resultados reproducibles sin interfaz gráfica.

Vegeta es una herramienta enfocada: envía solicitudes HTTP a una tasa y mide cómo responde el servidor. No modela recorridos complejos de usuario con lógica condicional y no valida cuerpos de respuesta más allá de códigos de estado.

Si lo estás comparando con otras herramientas, las guías de pruebas de carga con k6 y pruebas de carga con JMeter cubren alternativas basadas en concurrencia. Para conceptos y métricas base, consulta el tutorial de pruebas de rendimiento de API.

Dónde encaja el testing funcional

Las pruebas de carga responden: “¿es lo suficientemente rápido?”.

No responden: “¿es correcto?”.

Una ejecución de Vegeta puede informar 100% de códigos 200 aunque el endpoint devuelva el usuario incorrecto, un precio obsoleto o un JSON mal formado. Para Vegeta, esas respuestas pueden seguir siendo rápidas y exitosas.

La corrección necesita otro tipo de validación:

  • Aserciones sobre el cuerpo de la respuesta.
  • Validación de esquema.
  • Reglas de negocio.
  • Encadenamiento de solicitudes.
  • Datos de prueba controlados.

Eso es testing funcional de API. El patrón recomendable es:

  1. Validar que la API responde correctamente.
  2. Ejecutar la prueba de carga sobre endpoints que ya pasaron esas validaciones.
  3. Comparar latencia, errores y throughput bajo una tasa objetivo.

Aquí es donde Apidog complementa a Vegeta. En Apidog puedes construir escenarios de prueba con aserciones visuales sobre estado, headers y campos JSON, encadenar solicitudes y usar archivos de datos. Luego Vegeta mide si ese flujo correcto se mantiene rápido cuando recibe cientos o miles de solicitudes por segundo.

Ejecutar pruebas funcionales con Apidog CLI antes de Vegeta

Apidog incluye una CLI para ejecutar escenarios funcionales en CI.

Instálala con Node:

npm install -g apidog-cli
Enter fullscreen mode Exit fullscreen mode

Ejecuta un escenario o suite guardado por ID:

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

Parámetros principales:

  • -t: ID del escenario, carpeta o suite.
  • -e: ID del entorno.
  • -r: reporteros, por ejemplo cli, html, json, junit.

La salida junit se integra con la mayoría de paneles de CI.

Consulta el tutorial de línea de comandos de Apidog CLI y la guía de pipeline de CI/CD para un flujo más completo.

Un pipeline simple podría verse así:

# 1. Puerta funcional
apidog run --access-token "$APIDOG_ACCESS_TOKEN" \
  -t <scenarioOrSuiteId> \
  -e <environmentId> \
  -r cli,junit

# 2. Prueba de carga solo si lo funcional pasó
vegeta attack \
  -targets=targets.txt \
  -rate=200 \
  -duration=60s \
  -output=results.bin

# 3. Reporte
vegeta report results.bin
vegeta report -type=json results.bin > metrics.json
Enter fullscreen mode Exit fullscreen mode

Preguntas frecuentes

¿Vegeta soporta solicitudes POST con body?

Sí. En el archivo de objetivos HTTP, coloca el método y la URL en la primera línea, añade un header Content-Type y referencia el cuerpo con @./payload.json.

POST http://localhost:8080/api/users
Content-Type: application/json
@./payload.json
Enter fullscreen mode Exit fullscreen mode

En formato JSON, usa method, url, header y un body codificado en base64.

¿Qué hace -rate=0?

Elimina el límite de tasa y envía solicitudes tan rápido como lo permitan los workers y las conexiones. Eso sirve para una prueba de máximo rendimiento, pero no para una medición controlada y repetible. Para capacidad bajo una carga objetivo, define una tasa explícita.

¿Cómo leo los percentiles de latencia?

La línea Latencies muestra mínimo, media, percentiles 50, 90, 95, 99 y máximo. Concéntrate en 95 y 99, porque describen la cola lenta que puede ocultar una media saludable.

¿Puede Vegeta verificar que mi API devuelve datos correctos?

No. Vegeta mide rendimiento, latencia, códigos de estado y errores de transporte. No hace aserciones sobre cuerpos de respuesta, esquemas o reglas de negocio. Combínalo con testing funcional para validar corrección antes de medir carga.

¿Cómo ejecuto Vegeta en CI?

Vegeta es un binario que lee entrada estándar y escribe resultados, así que encaja en cualquier paso de shell. Guarda los resultados con -output, genera informes con vegeta report y publica results.bin, metrics.json o plot.html como artefactos. Añade una puerta funcional antes del paso de carga para medir solo endpoints que ya pasaron sus aserciones.

Top comments (0)