DEV Community

Cover image for wrk: Cómo realizar pruebas de carga a una API desde la línea de comandos
Roobia
Roobia

Posted on • Originally published at apidog.com

wrk: Cómo realizar pruebas de carga a una API desde la línea de comandos

Enviaste un endpoint. Funciona en tu navegador. Pero no sabes qué pasa cuando 400 usuarios lo llaman al mismo tiempo: si la latencia se mantiene estable, si el p99 se dispara o si el servidor cae antes de llegar a 1,000 requests por segundo.

Prueba Apidog hoy

wrk te ayuda a medirlo. Es una herramienta de línea de comandos para generar tráfico HTTP contra una URL y ver cómo responde tu servidor bajo carga.

Qué es wrk y cuándo usarlo

wrk es una herramienta moderna de benchmarking HTTP. Genera carga desde una única máquina de múltiples núcleos y mide dos cosas clave:

  • Latencia de las respuestas.
  • Requests por segundo que el servidor puede completar.

Internamente usa multithreading y un bucle de eventos escalable, como epoll en Linux o kqueue en macOS. Por eso puede generar bastante tráfico desde una sola máquina sin montar una flota de generadores de carga.

Usa wrk cuando quieras responder preguntas como:

  • ¿Cuántas solicitudes por segundo soporta este endpoint?
  • ¿Cuál es la latencia media, p90 y p99?
  • ¿El rendimiento se mantiene estable durante 30 segundos, 2 minutos o más?
  • ¿A partir de cuántas conexiones concurrentes empieza a degradarse el servidor?

Ten clara una limitación: wrk mide velocidad, no corrección. No valida que el JSON sea correcto, que el status code sea 200 o que el contrato de la API se mantenga. Para entender los conceptos de carga antes de ejecutar benchmarks, esta guía sobre pruebas de carga de API cubre el contexto que wrk pone en práctica.

Instalación de wrk

macOS

La forma más simple es Homebrew:

brew install wrk
Enter fullscreen mode Exit fullscreen mode

En Apple Silicon, esto evita problemas comunes al compilar manualmente con LuaJIT ARM64.

Verifica la instalación:

wrk --version
Enter fullscreen mode Exit fullscreen mode

Linux

En Linux normalmente lo compilas desde el código fuente. Primero instala dependencias:

sudo apt-get install build-essential libssl-dev git -y
Enter fullscreen mode Exit fullscreen mode

Clona el repositorio y compila:

git clone https://github.com/wg/wrk.git
cd wrk
make
Enter fullscreen mode Exit fullscreen mode

El binario queda en el directorio actual. Muévelo a tu PATH:

sudo cp wrk /usr/local/bin
Enter fullscreen mode Exit fullscreen mode

Confirma que funciona:

wrk --version
Enter fullscreen mode Exit fullscreen mode

Ejecutar tu primer benchmark

La forma básica de wrk es:

wrk -t12 -c400 -d30s http://127.0.0.1:8080/index.html
Enter fullscreen mode Exit fullscreen mode

Parámetros principales:

  • -t, --threads: número de hilos del sistema operativo. Un buen punto de partida es un hilo por núcleo de CPU.
  • -c, --connections: número total de conexiones HTTP abiertas. Sirve para simular clientes concurrentes.
  • -d, --duration: duración de la prueba. Acepta valores como 30s, 2m o 2h.

Ejemplo práctico para un endpoint local:

wrk -t8 -c200 -d30s --latency http://localhost:3000/api/users
Enter fullscreen mode Exit fullscreen mode

Este comando ejecuta:

  • 8 hilos.
  • 200 conexiones concurrentes.
  • 30 segundos de carga.
  • Reporte detallado de latencia con --latency.

Dos opciones útiles para casi cualquier prueba:

--latency
Enter fullscreen mode Exit fullscreen mode

Muestra percentiles de latencia. Actívala casi siempre, porque los promedios ocultan problemas de cola.

--timeout 2s
Enter fullscreen mode Exit fullscreen mode

Marca como timeout cualquier request que no reciba respuesta dentro de 2 segundos. Esto evita que respuestas extremadamente lentas distorsionen tus métricas.

Ejemplo completo:

wrk -t8 -c200 -d30s --timeout 2s --latency http://localhost:3000/api/users
Enter fullscreen mode Exit fullscreen mode

Cómo leer la salida de wrk

Una ejecución típica se ve así:

Running 5s test @ http://10.135.232.163:3000
  2 threads and 5 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency     3.82ms    2.64ms  26.68ms   85.81%
    Req/Sec   550.90    202.40     0.98k    68.00%
  5494 requests in 5.01s, 1.05MB read
Requests/sec:   1096.54
Transfer/sec:    215.24KB
Enter fullscreen mode Exit fullscreen mode

Léelo de abajo hacia arriba.

Requests/sec

Requests/sec:   1096.54
Enter fullscreen mode Exit fullscreen mode

Es el throughput promedio: cuántas solicitudes completó el servidor por segundo.

Úsalo para comparar:

  • Versión anterior vs nueva versión.
  • Endpoint A vs endpoint B.
  • Configuración actual vs configuración optimizada.
  • HTTP vs HTTPS.
  • Distintos niveles de concurrencia.

Transfer/sec

Transfer/sec:    215.24KB
Enter fullscreen mode Exit fullscreen mode

Indica cuántos datos se transfirieron por segundo. Es útil si sospechas que el cuello de botella está en red o en payloads grandes.

Latency

Latency     3.82ms    2.64ms  26.68ms   85.81%
Enter fullscreen mode Exit fullscreen mode

Significa:

  • Promedio: 3.82ms.
  • Desviación estándar: 2.64ms.
  • Máximo: 26.68ms.

Si el máximo está muy lejos del promedio, hay solicitudes que tardan mucho más que la mayoría. Eso suele afectar la experiencia real del usuario.

Percentiles de latencia

Con --latency, wrk añade un bloque como este:

  Latency Distribution
     50%    3.21ms
     75%    4.86ms
     90%    7.09ms
     99%   14.13ms
Enter fullscreen mode Exit fullscreen mode

El número más importante suele ser el p99:

  • 50%: la mitad de las requests termina en 3.21ms o menos.
  • 90%: el 90% termina en 7.09ms o menos.
  • 99%: el 99% termina en 14.13ms o menos.

Si el promedio es bajo pero el p99 es alto, tienes latencia de cola. En producción, eso significa que una parte pequeña pero real de usuarios tendrá respuestas lentas.

Probar POST, JSON y cabeceras con Lua

Por defecto, wrk envía requests GET.

Para enviar POST, definir un body o usar cabeceras personalizadas, crea un script Lua y pásalo con -s.

Crea post.lua:

wrk.method = "POST"
wrk.body   = '{"name": "Ada", "role": "engineer"}'
wrk.headers["Content-Type"] = "application/json"
Enter fullscreen mode Exit fullscreen mode

Ejecútalo así:

wrk -t4 -c100 -d30s -s post.lua --latency http://localhost:3000/api/users
Enter fullscreen mode Exit fullscreen mode

Este benchmark envía requests POST con JSON a /api/users.

Para formularios application/x-www-form-urlencoded, usa:

wrk.method = "POST"
wrk.body   = "foo=bar&baz=quux"
wrk.headers["Content-Type"] = "application/x-www-form-urlencoded"
Enter fullscreen mode Exit fullscreen mode

También puedes añadir cabeceras simples con -H, sin script Lua:

wrk -t4 -c100 -d30s \
  -H "Authorization: Bearer TOKEN123" \
  --latency \
  http://localhost:3000/api/protected
Enter fullscreen mode Exit fullscreen mode

Regla práctica:

  • Usa -H para una o dos cabeceras.
  • Usa Lua cuando necesites body, método distinto de GET o lógica por request.

Encontrar el punto de saturación

No ejecutes una sola prueba y des por bueno el resultado. Sube la concurrencia gradualmente.

Por ejemplo:

wrk -t8 -c50  -d30s --latency http://localhost:3000/api/users
wrk -t8 -c100 -d30s --latency http://localhost:3000/api/users
wrk -t8 -c200 -d30s --latency http://localhost:3000/api/users
wrk -t8 -c400 -d30s --latency http://localhost:3000/api/users
Enter fullscreen mode Exit fullscreen mode

Observa tres señales:

  1. Requests/sec deja de subir.
  2. El p99 aumenta bruscamente.
  3. Aparecen timeouts o errores de socket.

Cuando el throughput se aplana y la latencia sube, encontraste una zona de saturación.

También vigila la máquina que ejecuta wrk. Si tu cliente está al 100% de CPU, puedes estar midiendo el límite del generador de carga, no el del servidor.

Los límites: wrk no valida la respuesta

wrk te dice qué tan rápido respondió el servidor. No te dice si respondió bien.

Si apuntas wrk a un endpoint que devuelve 500 en cada request, puede mostrar un reporte limpio con muchos requests por segundo. Para wrk, un intercambio HTTP completado cuenta como request completada.

No valida:

  • Status code.
  • Body JSON.
  • Esquema de respuesta.
  • Reglas de negocio.
  • Contrato de la API.

Además, los errores pueden parecer rápidos, porque el servidor hace menos trabajo cuando falla temprano.

Por eso wrk responde:

¿Es suficientemente rápido bajo carga?

Pero no responde:

¿Es correcto?

Ambas preguntas importan. Una cifra de rendimiento sobre un endpoint roto no es una métrica confiable. Por eso muchos equipos combinan benchmarking con una suite de pruebas funcionales.

Dónde encajan Apidog y las pruebas funcionales

Un flujo práctico tiene dos capas.

1. Valida el comportamiento

Antes de medir rendimiento, valida que el endpoint funciona correctamente.

En Apidog puedes crear escenarios de prueba que envían requests reales y verifican:

  • Códigos de estado.
  • Campos JSON.
  • Esquema de respuesta.
  • Datos entre pasos.
  • Lógica de negocio.
  • Comportamiento por entorno.

Esta capa detecta el 500 que wrk mediría sin quejarse.

2. Mide rendimiento

Cuando el comportamiento ya está validado, ejecuta wrk contra los mismos endpoints para medir concurrencia, throughput y latencia.

Apidog también tiene pruebas de rendimiento integradas si prefieres mantener pruebas funcionales y de carga en un solo lugar. Pero wrk sigue siendo una gran opción para benchmarking puro desde la terminal.

Ejecutar validaciones funcionales en CI con Apidog CLI

La validación funcional debería correr en CI, no solo en tu laptop.

Instala la CLI:

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

Ejecuta un escenario o suite guardada 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:

  • --access-token: token de acceso de Apidog.
  • -t: ID del escenario, carpeta o suite.
  • -e: ID del entorno.
  • -r: formatos de reporte, como cli, html, json o junit.

Para ejecuciones basadas en datos, añade -d o --iteration-data:

apidog run \
  --access-token "$APIDOG_ACCESS_TOKEN" \
  -t <scenarioOrSuiteId> \
  -e <environmentId> \
  -d ./data.csv \
  -r cli,junit
Enter fullscreen mode Exit fullscreen mode

La CLI de Apidog es headless. Ejecuta escenarios y suites guardados, pero no es un generador de carga. Úsala como puerta de verificación funcional. Usa wrk como medidor de rendimiento.

Para integrarlo en pipelines, revisa este tutorial de CI/CD con la CLI de Apidog o la guía de GitHub Actions. La referencia completa de la CLI cubre el resto de las banderas.

Preguntas frecuentes

¿Cuál es la diferencia entre wrk y ab?

wrk y ab envían carga HTTP e informan requests por segundo.

La diferencia principal es que wrk es multihilo y usa un bucle de eventos, por lo que suele generar más carga desde una sola máquina y manejar mejor alta concurrencia. ab es de un solo hilo.

Ninguno valida la corrección de la respuesta.

¿Cuántos hilos y conexiones debo usar?

Empieza con un hilo por núcleo de CPU.

Si tienes 8 núcleos y quieres simular 200 clientes concurrentes:

wrk -t8 -c200 -d30s --latency http://localhost:3000/api/users
Enter fullscreen mode Exit fullscreen mode

Luego aumenta -c hasta que:

  • Requests/sec deje de subir.
  • El p99 suba demasiado.
  • Aparezcan timeouts.
  • El cliente o el servidor lleguen a su límite.

¿wrk puede probar endpoints HTTPS?

Sí. Usa una URL https://:

wrk -t8 -c200 -d30s --latency https://api.example.com/users
Enter fullscreen mode Exit fullscreen mode

Ten en cuenta que TLS añade costo de CPU en cliente y servidor. Es normal ver menor throughput en HTTPS que en HTTP plano.

¿wrk valida el body o el status code?

No.

wrk cuenta intercambios HTTP completados y mide tiempo. No afirma status codes ni cuerpos de respuesta.

Para validar corrección, usa una suite funcional, por ejemplo ejecutada con Apidog CLI. Después usa wrk para medir rendimiento.

¿Cuánto debe durar una prueba de carga?

Depende del objetivo.

Para una comprobación rápida, unos segundos pueden servir:

wrk -t4 -c50 -d5s http://localhost:3000/api/users
Enter fullscreen mode Exit fullscreen mode

Para números más estables, usa al menos 30 segundos:

wrk -t8 -c200 -d30s --latency http://localhost:3000/api/users
Enter fullscreen mode Exit fullscreen mode

Para detectar degradación sostenida, fugas lentas o efectos de caché, ejecuta varios minutos:


bash
wrk -t8 -c200 -d5m --latency http://localhost:3000/api/users
Enter fullscreen mode Exit fullscreen mode

Top comments (0)