--- title: "Cómo hacer benchmarking HTTP con wrk y siege en Ubuntu" description: "Instala wrk y siege en Ubuntu 24.04, mide peticiones por segundo y latencia p99 de tu servidor web, prueba APIs con scripts Lua y aumenta la carga por fases." category: "Optimización de Rendimiento" language: es source: https://cubepath.com/es/docs/optimización-de-rendimiento/benchmarking-con-wrk-y-siege updated: 2026-09-25 --- # Cómo hacer benchmarking HTTP con wrk y siege en Ubuntu wrk y siege son dos herramientas de línea de comandos para someter un servidor web a carga y medir cuántas peticiones atiende y con qué latencia. wrk genera mucha carga con pocos recursos y es ideal para medir el máximo rendimiento de un endpoint; siege simula usuarios que recorren varias URL, lo que se acerca más al tráfico real. En este tutorial instalarás ambas en Ubuntu 24.04, lanzarás pruebas contra tu servidor, usarás scripts Lua para probar una API y aprenderás a interpretar los resultados. ## Requisitos previos Para seguir esta guía necesitas: - Un servidor objetivo con un servidor web o una aplicación HTTP en marcha (Nginx, Apache, una API...), accesible en `your_server_ip` o `your_domain`. - Una segunda máquina con Ubuntu 24.04 LTS que actuará como cliente de carga, por ejemplo un VPS de CubePath en la misma ubicación que el servidor. Así mides el servidor y no tu conexión doméstica. - Un usuario no root con privilegios `sudo` en el cliente. - Permiso para probar el servidor. Nunca lances pruebas de carga contra sistemas de terceros: para el destino es indistinguible de un ataque de denegación de servicio. > Nota: puedes ejecutar wrk en el mismo servidor contra `127.0.0.1` para pruebas rápidas, pero el cliente y el servidor compiten por la misma CPU y los resultados salen distorsionados. ## Paso 1: Instalar wrk y siege Ambas herramientas están en el repositorio `universe` de Ubuntu 24.04. Instálalas en la máquina cliente: ```bash sudo apt update sudo apt install wrk siege ``` Comprueba las versiones instaladas: ```bash wrk --version siege --version ``` ```output wrk 4.1.0 [epoll] Copyright (C) 2012 Will Glozer ... SIEGE 4.0.7 ... ``` ## Paso 2: Preparar el cliente de carga Cada conexión abierta consume un descriptor de fichero. El límite por defecto de una sesión es 1024, que se queda corto en cuanto pruebas con cientos de conexiones. Súbelo para la sesión actual: ```bash ulimit -n 65535 ulimit -n ``` ```output 65535 ``` El cambio solo afecta a la terminal actual, que es justo lo que necesitas para las pruebas. Consulta también cuántos núcleos tiene el cliente, porque de ahí sale el número de hilos de wrk: ```bash nproc ``` ## Paso 3: Lanzar la primera prueba con wrk wrk usa tres parámetros principales: - `-t`: número de hilos. Usa como máximo el número de núcleos del cliente. - `-c`: conexiones HTTP abiertas en total, repartidas entre los hilos. - `-d`: duración de la prueba (`30s`, `2m`...). Lanza una prueba de 30 segundos con 4 hilos y 100 conexiones, pidiendo la distribución de latencias con `--latency`: ```bash wrk -t4 -c100 -d30s --latency http://your_server_ip/ ``` ```output Running 30s test @ http://your_server_ip/ 4 threads and 100 connections Thread Stats Avg Stdev Max +/- Stdev Latency 4.21ms 2.03ms 48.10ms 88.12% Req/Sec 6.04k 512.33 7.21k 70.25% Latency Distribution 50% 3.87ms 75% 4.95ms 90% 6.30ms 99% 11.42ms 721893 requests in 30.02s, 585.21MB read Requests/sec: 24047.10 Transfer/sec: 19.49MB ``` Cómo leer el resultado: - **Requests/sec**: peticiones completadas por segundo. Es la cifra de rendimiento total. - **Latency Distribution**: percentiles de latencia. El p99 (99 %) indica cuánto espera el 1 % de peticiones más lentas y suele ser más útil que la media. - **Stdev** alta respecto a la media indica tiempos de respuesta irregulares (bloqueos, recolección de basura, disco lento). - Si aparecen líneas `Socket errors` o `Non-2xx or 3xx responses`, parte de las peticiones fallaron y el resultado no es válido como medida de rendimiento: revisa los logs del servidor antes de seguir. Para enviar cabeceras, por ejemplo un token de autenticación, usa `-H`: ```bash wrk -t4 -c100 -d30s -H "Authorization: Bearer your_token" http://your_server_ip/api/status ``` ## Paso 4: Probar una API con scripts Lua wrk puede cargar un script Lua con `-s` para cambiar el método, el cuerpo o las rutas de cada petición. Crea un script que envíe un POST con JSON: ```bash nano post.lua ``` ```lua wrk.method = "POST" wrk.body = '{"name": "test", "quantity": 1}' wrk.headers["Content-Type"] = "application/json" ``` Ejecútalo contra el endpoint de tu API: ```bash wrk -t2 -c50 -d30s --latency -s post.lua http://your_server_ip/api/items ``` > Advertencia: un POST real crea registros en la base de datos. Ejecuta este tipo de prueba contra un entorno de pruebas o un endpoint preparado para ello. Para repartir la carga entre varias rutas, define la función `request`, que wrk llama antes de cada petición. Crea `paths.lua`: ```bash nano paths.lua ``` ```lua local paths = { "/", "/about", "/api/status" } local i = 0 request = function() i = (i % #paths) + 1 return wrk.format("GET", paths[i]) end done = function(summary, latency, requests) io.write(string.format("Peticiones: %d, errores de estado: %d\n", summary.requests, summary.errors.status)) io.write(string.format("p50: %.2f ms, p99: %.2f ms\n", latency:percentile(50) / 1000, latency:percentile(99) / 1000)) end ``` La función `done` se ejecuta al terminar y recibe las latencias en microsegundos, por eso se dividen entre 1000. Lanza la prueba: ```bash wrk -t4 -c100 -d30s -s paths.lua http://your_server_ip ``` Al final de la salida habitual verás tus propias líneas: ```output Peticiones: 698412, errores de estado: 0 p50: 3.95 ms, p99: 12.10 ms ``` ## Paso 5: Simular usuarios con siege siege funciona con usuarios concurrentes (`-c`) que repiten peticiones durante un tiempo (`-t`, con sufijo `S`, `M` o `H`). Lanza 25 usuarios durante un minuto: ```bash siege -c 25 -t 1M http://your_server_ip/ ``` La primera vez que lo ejecutes, siege crea su configuración de usuario en `~/.siege/siege.conf`. Al terminar muestra un resumen: ```output Transactions: 41250 hits Availability: 100.00 % Elapsed time: 59.87 secs Data transferred: 33.41 MB Response time: 0.04 secs Transaction rate: 688.99 trans/sec Throughput: 0.56 MB/sec Concurrency: 24.93 Successful transactions: 41250 Failed transactions: 0 Longest transaction: 0.31 Shortest transaction: 0.00 ``` Los campos clave son **Availability** (porcentaje de peticiones correctas), **Transaction rate** (transacciones por segundo), **Response time** (tiempo medio de respuesta) y **Longest transaction**. Si `Concurrency` queda muy por debajo del número de usuarios, el servidor responde tan rápido que los usuarios pasan tiempo esperando; si se acerca, el servidor empieza a ser el cuello de botella. Por defecto siege introduce una pausa aleatoria entre peticiones de cada usuario, lo que imita a una persona navegando. Para medir el máximo rendimiento sin pausas usa el modo benchmark `-b`: ```bash siege -b -c 50 -t 30S http://your_server_ip/ ``` ### Probar varias URL La ventaja de siege es que puede recorrer una lista de URL, incluidas peticiones POST. Crea el fichero: ```bash nano urls.txt ``` ```text http://your_server_ip/ http://your_server_ip/about http://your_server_ip/api/status http://your_server_ip/api/items POST {"name": "test", "quantity": 1} ``` Ejecuta siege en modo internet (`-i`), que elige una URL al azar en cada petición, con una pausa de hasta 1 segundo (`-d 1`) entre peticiones de cada usuario: ```bash siege -c 50 -t 2M -i -d 1 -f urls.txt --content-type "application/json" ``` Las cabeceras se añaden con `-H`, igual que en wrk: ```bash siege -c 25 -t 1M -H "Authorization: Bearer your_token" http://your_server_ip/api/status ``` ## Paso 6: Aumentar la carga por fases Una única prueba no dice cuánta carga aguanta el servidor. Lo útil es subir las conexiones por fases y ver dónde deja de crecer el rendimiento y empieza a dispararse la latencia. Este bucle ejecuta wrk con cargas crecientes y muestra solo las líneas relevantes: ```bash for c in 10 50 100 200 400; do echo "== ${c} conexiones" wrk -t4 -c"${c}" -d30s --latency http://your_server_ip/ \ | grep -E 'Requests/sec|^ +99%|Socket errors|Non-2xx' done ``` ```output == 10 conexiones 99% 1.20ms Requests/sec: 9120.44 == 50 conexiones 99% 3.10ms Requests/sec: 21875.02 == 100 conexiones 99% 11.42ms Requests/sec: 24047.10 == 200 conexiones 99% 38.75ms Requests/sec: 24310.66 == 400 conexiones 99% 121.30ms Requests/sec: 23980.18 ``` En este ejemplo el rendimiento se estabiliza en unas 24 000 peticiones por segundo a partir de 100 conexiones, mientras la latencia p99 sigue subiendo. Ese es el punto de saturación: más conexiones solo generan cola. Mientras corre la prueba, observa el servidor desde otra terminal para saber qué recurso se agota: ```bash vmstat 1 ``` Si la columna `us` + `sy` se acerca al 100 %, el límite es la CPU; si `wa` es alta, el disco; si ninguna lo es, busca límites de la aplicación (workers, pool de conexiones a la base de datos). Vigila también la CPU del cliente con `top`: si wrk ocupa todos sus núcleos, el cuello de botella es el cliente y necesitas una máquina más grande para medir. Para comparar antes y después de un cambio (activar caché, ajustar workers de PHP-FPM, etc.), ejecuta la misma prueba al menos tres veces en cada estado, con el mismo cliente y a la misma hora, y guarda los resultados: ```bash mkdir -p ~/benchmarks wrk -t4 -c100 -d60s --latency http://your_server_ip/ | tee ~/benchmarks/antes-$(date +%F-%H%M).txt ``` ## wrk o siege: cuál usar | | wrk | siege | |---|---|---| | Modelo de carga | Conexiones persistentes al máximo ritmo | Usuarios con pausas opcionales | | Rendimiento del cliente | Muy alto, pocos recursos | Moderado | | Varias URL | Con script Lua | Fichero de URL nativo | | Percentiles de latencia | Sí (`--latency`) | No, solo media y máximo | | Uso típico | Máximo rendimiento de un endpoint | Simular navegación y disponibilidad | Usa wrk para encontrar el techo de rendimiento y comparar configuraciones, y siege para comprobar cómo se comporta el sitio con un número realista de usuarios navegando. ## Solución de problemas **`Socket errors: connect ...` o `timeout ...` en wrk.** El servidor rechaza o no atiende conexiones. Revisa el log de errores del servidor web, el límite de conexiones (`worker_connections` en Nginx) y la cola del kernel (`net.core.somaxconn`). Los `timeout` se cuentan cuando una petición supera 2 segundos; puedes cambiarlo con `--timeout 5s`. **`too many open files`.** No has subido `ulimit -n` en la terminal donde lanzas la prueba (paso 2), o el servidor web tiene su propio límite de descriptores demasiado bajo. **siege no pasa de 255 usuarios.** siege limita la concurrencia con la directiva `limit` de `~/.siege/siege.conf`. Súbela si de verdad necesitas más usuarios, aunque para cargas altas wrk es más adecuado. **Resultados muy variables entre ejecuciones.** Suele deberse a caché fría en la primera ejecución, a otros procesos en el cliente o a pruebas demasiado cortas. Haz una ejecución de calentamiento que descartes y usa duraciones de 60 segundos o más. ## Conclusión Ahora sabes medir el rendimiento de un servidor web con wrk, probar APIs con scripts Lua, simular usuarios con siege y localizar el punto de saturación subiendo la carga por fases. Como siguientes pasos, puedes perfilar el servidor durante la prueba con `perf` para ver qué funciones consumen la CPU, ajustar la configuración de Nginx o PHP-FPM y repetir las mismas pruebas para cuantificar la mejora.