--- title: "Cómo medir el rendimiento web con Apache Bench (ab)" description: "Instala Apache Bench en Ubuntu 24.04, lanza pruebas de carga contra tu servidor web, interpreta peticiones por segundo y latencias y compara resultados." category: "Optimización de Rendimiento" language: es source: https://cubepath.com/es/docs/optimización-de-rendimiento/benchmarking-de-servidor-web-con-apache-bench-ab updated: 2026-09-25 --- # Cómo medir el rendimiento web con Apache Bench (ab) Apache Bench (`ab`) es una herramienta de línea de comandos que lanza un número fijo de peticiones HTTP contra una URL, con la concurrencia que indiques, y resume cuántas peticiones por segundo atendió el servidor y cuánto tardaron. Funciona contra cualquier servidor web, no solo Apache, y es útil para comparar el antes y el después de un cambio de configuración: activar OPcache, ajustar PHP-FPM o añadir una caché. En este tutorial instalarás `ab` en Ubuntu 24.04, lanzarás pruebas bien planteadas, interpretarás su salida y aprenderás a detectar cuándo el cuello de botella es el propio cliente y no el servidor. ## Requisitos previos Para seguir esta guía necesitas: - Una máquina con Ubuntu 24.04 LTS desde la que lanzar las pruebas y un usuario con privilegios `sudo`. Lo ideal es que sea distinta del servidor que vas a medir, por ejemplo un segundo VPS de CubePath en la misma región. - Un servidor web accesible por HTTP o HTTPS (`your_domain`) que sea tuyo o que tengas permiso para probar. > Advertencia: una prueba de carga contra un servidor ajeno puede considerarse un ataque de denegación de servicio. Mide solo tus propios servidores y, si están en producción, hazlo en horas de poco tráfico. ## Paso 1: Instalar Apache Bench `ab` forma parte del paquete `apache2-utils`, que no instala el servidor Apache: ```bash sudo apt update sudo apt install apache2-utils ``` Comprueba la versión: ```bash ab -V ``` ```output This is ApacheBench, Version 2.3 <$Revision: 1903618 $> ``` ## Paso 2: Lanzar la primera prueba Las dos opciones básicas son `-n`, el número total de peticiones, y `-c`, cuántas se hacen a la vez. Lanza 1.000 peticiones con 10 conexiones concurrentes: ```bash ab -n 1000 -c 10 https://your_domain/ ``` La URL debe incluir la ruta. `ab https://your_domain` sin la barra final falla con `ab: invalid URL`. Mientras la prueba corre, `ab` muestra el progreso cada 10 % de las peticiones y al final imprime un informe como este (resumido): ```output Server Software: nginx/1.24.0 Server Hostname: your_domain Server Port: 443 SSL/TLS Protocol: TLSv1.3,TLS_AES_256_GCM_SHA384,2048,256 Document Path: / Document Length: 18432 bytes Concurrency Level: 10 Time taken for tests: 4.812 seconds Complete requests: 1000 Failed requests: 0 Total transferred: 18771000 bytes HTML transferred: 18432000 bytes Requests per second: 207.81 [#/sec] (mean) Time per request: 48.120 [ms] (mean) Time per request: 4.812 [ms] (mean, across all concurrent requests) Transfer rate: 3809.43 [Kbytes/sec] received Connection Times (ms) min mean[+/-sd] median max Connect: 6 14 5.1 13 41 Processing: 21 34 11.8 31 162 Waiting: 20 32 11.5 29 160 Total: 28 48 13.2 45 189 Percentage of the requests served within a certain time (ms) 50% 45 66% 49 75% 52 80% 54 90% 63 95% 74 98% 92 99% 118 100% 189 (longest request) ``` ## Paso 3: Interpretar los resultados Los valores que realmente importan: - **Failed requests**: debe ser 0. Si no lo es, las demás cifras no son fiables (ver la sección de problemas). - **Non-2xx responses**: solo aparece si hubo respuestas con error, redirecciones o códigos distintos de 2xx. Una prueba contra una URL que devuelve `301` mide la redirección, no tu página. - **Requests per second**: el rendimiento (throughput) medio. Es la cifra que más se compara, pero por sí sola no dice nada de la experiencia del usuario. - **Time per request (mean)**: el tiempo medio que ha esperado cada cliente. El segundo valor, "across all concurrent requests", es simplemente el tiempo total dividido entre el número de peticiones. - **Connection Times**: `Connect` es el tiempo de establecer la conexión TCP y TLS; `Waiting` es el tiempo hasta el primer byte de la respuesta, que refleja lo que tarda la aplicación; `Processing` incluye además la descarga. - **Percentiles**: el 95 % de las peticiones terminó en 74 ms o menos. Los percentiles 95 y 99 muestran las peticiones lentas que la media esconde, y son los que conviene vigilar al optimizar. En el ejemplo, `Connect` supone casi un tercio del tiempo total porque cada petición abre una conexión TLS nueva. Eso lleva a la siguiente opción. ## Paso 4: Usar keep-alive y cabeceras realistas Por defecto `ab` abre una conexión nueva por cada petición, algo que un navegador no hace. Con `-k` reutiliza las conexiones mediante keep-alive, lo que se parece más al tráfico real y mide mejor el tiempo de la aplicación: ```bash ab -n 1000 -c 10 -k https://your_domain/ ``` ```output Keep-Alive requests: 1000 Requests per second: 412.37 [#/sec] (mean) ``` `ab` tampoco pide respuestas comprimidas por defecto. Si quieres medir con compresión, como haría un navegador, añade la cabecera con `-H`: ```bash ab -n 1000 -c 10 -k -H 'Accept-Encoding: gzip, br' https://your_domain/ ``` Otras opciones útiles: | Opción | Uso | |--------|-----| | `-t 30` | Dura 30 segundos en lugar de un número fijo de peticiones | | `-s 60` | Tiempo máximo de espera por respuesta en segundos (por defecto 30) | | `-C 'nombre=valor'` | Envía una cookie, por ejemplo para medir páginas de un usuario autenticado | | `-H 'Cabecera: valor'` | Añade una cabecera; se puede repetir | | `-l` | Acepta respuestas de longitud variable sin contarlas como fallidas | | `-e resultados.csv` | Guarda en CSV el tiempo de cada percentil del 0 al 100 | ## Paso 5: Probar peticiones POST Para medir un endpoint que recibe datos, guarda el cuerpo en un fichero e indica el tipo de contenido con `-T`. Por ejemplo, para una API JSON: ```bash echo '{"query": "test"}' > ~/body.json ab -n 500 -c 10 -k -p ~/body.json -T 'application/json' https://your_domain/api/search ``` Ten en cuenta que cada petición se ejecuta de verdad: no hagas pruebas POST contra endpoints que crean pedidos, envían correos o escriben datos en producción. ## Paso 6: Comparar configuraciones de forma fiable Una medida aislada vale poco; lo útil es comparar. Para que la comparación sea válida: 1. Lanza una prueba corta de calentamiento y descártala. Las primeras peticiones llenan cachés como OPcache y el buffer de la base de datos. 2. Repite cada prueba al menos tres veces con los mismos parámetros y quédate con la mediana. 3. Cambia una sola cosa entre una tanda y la siguiente. 4. Sube la concurrencia de forma escalonada para ver dónde deja de crecer el rendimiento. Un bucle sencillo: ```bash for c in 1 10 25 50 100; do printf 'c=%-4s ' "$c" ab -n 2000 -c "$c" -k https://your_domain/ 2>/dev/null | grep -E 'Requests per second' done ``` ```output c=1 Requests per second: 96.40 [#/sec] (mean) c=10 Requests per second: 412.37 [#/sec] (mean) c=25 Requests per second: 538.12 [#/sec] (mean) c=50 Requests per second: 551.03 [#/sec] (mean) c=100 Requests per second: 549.87 [#/sec] (mean) ``` En este ejemplo el servidor se satura en torno a 25-50 conexiones concurrentes: más concurrencia ya no aumenta las peticiones por segundo, solo la latencia. Mientras corre la prueba, observa el servidor con `htop` o `vmstat 1` para ver si el límite es la CPU, la memoria o los procesos de PHP-FPM. ## Limitaciones de Apache Bench - Usa HTTP/1.0 y un solo hilo. En servidores muy rápidos, o con HTTPS y mucha concurrencia, el cuello de botella puede ser el propio `ab`. Si ves que `ab` consume el 100 % de un núcleo en la máquina cliente, los resultados miden al cliente, no al servidor. - Pide una sola URL, sin cargar imágenes, CSS ni JavaScript, y no ejecuta JavaScript. No sustituye a una prueba con navegador. - Medir desde el mismo servidor elimina la red y compite por la CPU con el servidor web. Úsalo solo para pruebas rápidas. Para cargas más altas, herramientas como `wrk` (disponible en Ubuntu con `sudo apt install wrk`) usan varios hilos y generan mucha más carga desde la misma máquina. ## Solución de problemas - **`Failed requests` con `Length` distinto de 0**: la página devuelve contenido de tamaño variable (fechas, tokens CSRF, anuncios) y `ab` lo cuenta como fallo al compararlo con la primera respuesta. Si el contenido es correcto, repite la prueba con `-l`. - **`socket: Too many open files (24)`**: la concurrencia supera el límite de descriptores de fichero de tu sesión. Súbelo antes de lanzar la prueba con `ulimit -n 10000`. - **`apr_socket_recv: Connection reset by peer (104)`**: el servidor ha cerrado conexiones, normalmente por un límite de conexiones, un rate limit o un cortafuegos que ha detectado la prueba. Revisa los logs del servidor web y reduce la concurrencia. - **`apr_pollset_poll: The timeout specified has expired (70007)`**: el servidor tarda más de 30 segundos en responder. Súbelo con `-s` si es esperado o investiga la causa en el servidor. ## Conclusión Ya sabes lanzar pruebas de carga con Apache Bench, leer las cifras que importan (errores, peticiones por segundo y percentiles de latencia) y comparar configuraciones de forma fiable. Como siguientes pasos, usa estas mediciones para validar cambios como activar OPcache, ajustar los pools de PHP-FPM o añadir una caché con Memcached, y prueba `wrk` cuando necesites generar más carga de la que `ab` puede producir.