Tutoriales de VPS
TTFB alto en un sitio web en VPS (2026): tiempo hasta el primer byte, Nginx, PHP-FPM, base de datos y diagnóstico con Cloudflare
Cuando un sitio web en VPS carga lento pero el ancho de banda no está saturado y la CPU no es alta, revisa primero el TTFB. Este artículo recorre en orden el waterfall del navegador, el tiempo con curl, upstream_time de Nginx, PHP-FPM, consultas lentas de base de datos, DNS/TLS y la petición al origen de Cloudflare.

TTFB alto en un sitio web en VPS (2026): tiempo hasta el primer byte, Nginx, PHP-FPM, base de datos y diagnóstico con Cloudflare
Mucha gente dice "el sitio web va lento", pero en realidad no es un solo problema.
Algunos sitios tienen imágenes demasiado grandes y las páginas descargan lento; otros tienen demasiado JS en el frontend y el navegador renderiza lento; y hay un tipo más molesto: la página se queda en blanco un rato antes de empezar a aparecer.
En este caso, lo primero que hay que mirar no es el ancho de banda ni el CDN, sino el TTFB.
TTFB es Time To First Byte, en español "tiempo hasta el primer byte". En pocas palabras, es cuánto tarda el navegador en recibir el primer byte devuelto por el servidor después de enviar la petición.
Si el TTFB es alto, la lentitud probablemente ocurre en:
- DNS / TLS / handshake de red
- Petición al origen del CDN
- Proxy inverso Nginx
- Aplicación PHP-FPM / Node / Python
- Consultas a la base de datos
- Fallos de caché
- CPU, I/O de disco y presión de memoria del VPS
Una vez ayudé a revisar un sitio WordPress cuyo TTFB de la página de inicio era de 2,8 segundos. Habían probado compresión de imágenes, cambiar de tema y activar Brotli, pero al final resultó que un plugin consultaba más de 400 registros de base de datos en cada carga de la página de inicio. Tras resolver las consultas lentas y el almacenamiento en caché de objetos, el TTFB bajó a unos 300 ms.
Así que este artículo no trata de "diez trucos para acelerar tu sitio web", sino de una sola cosa: cómo localizar en qué capa se atasca cuando el TTFB es alto.
No lo juzgues por intuición.
Abre las herramientas de desarrollador en el navegador, ve a Network, recarga la página y mira el Timing de la petición HTML principal.
Fíjate en:
| Fase | Descripción |
|---|---|
| DNS Lookup | Tiempo de resolución del dominio |
| Initial connection | Tiempo de conexión TCP |
| SSL | Tiempo del handshake TLS |
| Waiting for server response | Normalmente es la parte central del TTFB |
| Content Download | Tiempo de descarga del contenido |
Si lo lento es Content Download, puede que la página sea demasiado grande, las imágenes demasiado grandes o el ancho de banda lento.
Si lo lento es Waiting for server response, ese es el problema de TTFB que trata este artículo.
También puedes medirlo con un comando:
curl -o /dev/null -s -w 'dns:%{time_namelookup}\nconnect:%{time_connect}\ntls:%{time_appconnect}\nttfb:%{time_starttransfer}\ntotal:%{time_total}\n' https://example.com/
La salida podría ser:
dns:0.012
connect:0.080
tls:0.160
ttfb:2.431
total:2.620
Esto lo deja claro: lo que realmente es lento es el primer byte, no la descarga.
Un TTFB alto no significa necesariamente que el servidor sea lento; también puede ser un problema de ruta de red.
Prueba desde al menos dos lugares:
curl -o /dev/null -s -w '%{time_starttransfer}\n' https://example.com/
Puedes probar desde:
- Tu ordenador local
- El propio VPS
- Un servidor en otra región
- El panel de Cloudflare / WebPageTest / PageSpeed Insights
Si el propio VPS accede rápido:
curl -o /dev/null -s -w '%{time_starttransfer}\n' http://127.0.0.1/
Pero tu acceso local es lento, puede ser:
- Resolución DNS lenta
- Ruta de red transfronteriza lenta
- Petición al origen del nodo CDN lenta
- Inestabilidad de red en horas punta
Si el propio VPS también va lento, el problema probablemente está en la aplicación, Nginx, la base de datos o los recursos de la máquina.
Para temas de horas punta, consulta: Por qué el VPS se ralentiza en horas punta.
Si usas Cloudflare u otro CDN, no culpes al origen de inmediato.
Prueba dos rutas por separado:
- El usuario accede al CDN
- El CDN pide al origen en el VPS
Si el dominio pasa por Cloudflare, puedes probar temporalmente con la IP del origen:
curl -H 'Host: example.com' -o /dev/null -s -w 'ttfb:%{time_starttransfer} total:%{time_total}\n' http://YOUR_ORIGIN_IP/
Si el origen es rápido pero a través de Cloudflare va lento, puede ser:
- Ruta de red lenta del nodo CDN al origen
- Reglas de seguridad / inspección WAF de Cloudflare que tardan
- Reglas de caché que no coinciden
- Problemas con el protocolo de origen, TLS o configuración de redirecciones
Si el propio origen es lento, el CDN solo está dejando al descubierto la lentitud.
Para problemas de origen con Cloudflare, consulta: Qué hacer ante Cloudflare 521 / 522 en un sitio web en VPS.
Muchas veces necesitas saber: ¿la lentitud está en Nginx o en la aplicación detrás de Nginx?
El log por defecto de Nginx no necesariamente tiene estos campos, así que conviene añadir temporalmente un log_format más útil:
log_format timing '$remote_addr - $host "$request" '
'status=$status request_time=$request_time '
'upstream_response_time=$upstream_response_time '
'upstream_connect_time=$upstream_connect_time '
'upstream_header_time=$upstream_header_time';
access_log /var/log/nginx/access_timing.log timing;
Comprueba la configuración:
nginx -t
systemctl reload nginx
Luego visita la página varias veces y vuelve a mirar:
tail -f /var/log/nginx/access_timing.log
Podrías ver:
status=200 request_time=2.845 upstream_response_time=2.801 upstream_header_time=2.801
Esto significa que la mayor parte del tiempo se gasta en la aplicación upstream.
Si es:
request_time=2.800 upstream_response_time=-
Entonces puede ser archivos estáticos, que Nginx lo gestione él mismo, espera de conexión u otros problemas de configuración.
Para errores de configuración de Nginx, consulta: Qué hacer ante errores de configuración de Nginx en VPS.
Si ejecutas un sitio PHP como WordPress, Laravel o Typecho, el TTFB alto suele venir de PHP-FPM.
Primero mira el estado del servicio:
systemctl status php8.2-fpm
Mira los logs:
journalctl -u php8.2-fpm -n 100 --no-pager
Ajusta el número de versión según tu sistema, por ejemplo php8.1-fpm, php8.3-fpm.
Fíjate en estas señales:
server reached pm.max_children setting
child exited on signal
slow request
pool www seems busy
Si ves pm.max_children al máximo, significa que no hay suficientes workers PHP o que las peticiones individuales son demasiado lentas.
Puedes ver el número de procesos:
ps aux | grep php-fpm | wc -l
También puedes activar el slowlog de PHP-FPM:
request_slowlog_timeout = 5s
slowlog = /var/log/php-fpm/www-slow.log
Luego recarga PHP-FPM.
Si tu sitio WordPress va lento, sigue leyendo: Qué hacer cuando WordPress va lento en un VPS.
Si la página consulta la base de datos cada vez, una base de datos algo lenta hará subir el TTFB directamente.
En MySQL / MariaDB, primero comprueba si el log de consultas lentas está activado:
SHOW VARIABLES LIKE 'slow_query_log';
SHOW VARIABLES LIKE 'long_query_time';
Puedes activarlo temporalmente así:
SET GLOBAL slow_query_log = 'ON';
SET GLOBAL long_query_time = 1;
Luego mira la ubicación del log de consultas lentas:
SHOW VARIABLES LIKE 'slow_query_log_file';
Problemas habituales:
- Falta de índices
- Consultas duplicadas de plugins o temas
- La página de inicio consulta demasiados datos de una vez
- Base de datos y aplicación en regiones distintas
- Pool de conexiones de base de datos insuficiente
- Tablas demasiado grandes sin paginación
Si no quieres analizar SQL de inmediato, al menos comprueba si la base de datos tiene presión:
top
iotop -o
mysqladmin processlist
Que la base de datos no conecte o no arranque es otro problema; consulta: Qué hacer cuando MySQL / MariaDB no conecta en un VPS.
Muchos sitios pequeños tienen TTFB alto no porque la máquina sea mala, sino porque la caché no está bien configurada.
Puedes mirar primero las cabeceras de respuesta:
curl -I https://example.com/
Fíjate en estas:
cache-control
cf-cache-status
x-cache
server-timing
Si usas Cloudflare pero las páginas HTML siempre muestran:
cf-cache-status: DYNAMIC
Eso significa que Cloudflare no está cacheando HTML y pide al origen cada vez.
Esto es normal para el panel de administración, el carrito de compra y la página de inicio de sesión; pero si son páginas de contenido puro, páginas de blog o páginas de documentación, puedes considerar cachearlas.
Nginx también puede usar fastcgi_cache o proxy_cache, pero con cuidado:
- No cachees usuarios con sesión iniciada
- No cachees el panel de administración
- No cachees a la ligera páginas con cookies de estado de usuario
- No cachees envíos de formularios, pagos ni comentarios
Hacer mal la caché es más problemático que no hacerla.
Mucha gente mira top, ve que la CPU no está alta y piensa que la máquina está bien.
Pero el TTFB alto puede atascarse en:
- I/O de disco
- iowait
- Recuperación de memoria
- Oscilación de swap
- Cola de workers de PHP-FPM
- Espera de bloqueos de base de datos
Mira la carga del sistema:
uptime
Mira CPU, memoria, iowait:
vmstat 1
Mira el I/O de disco:
iostat -xz 1
Mira los procesos:
htop
Si wa es alto, o el util del disco se mantiene cerca del 100% durante mucho tiempo, puede que las peticiones estén todas esperando al disco.
En este caso, consulta: Qué hacer cuando el I/O de disco del VPS es muy alto.
El TTFB se mide desde que empieza la petición hasta el primer byte, y a veces DNS, conexión y TLS ya son lentos antes.
Con curl puedes desglosarlo:
curl -o /dev/null -s -w 'dns:%{time_namelookup}\nconnect:%{time_connect}\ntls:%{time_appconnect}\nttfb:%{time_starttransfer}\ntotal:%{time_total}\n' https://example.com/
Si solo dns ya son 0,8 segundos, no es que PHP vaya lento.
Si tls es alto, puede ser:
- Problemas de cadena de certificados
- Varias redirecciones HTTPS
- Modo SSL inadecuado entre origen y CDN
- Configuración anómala de HTTP/2 / HTTP/3
Comprueba la cadena de redirecciones:
curl -IL https://example.com/
Si aparecen redirecciones de ida y vuelta como http -> https -> www -> sin www -> https, el TTFB también se verá mal.
Para bucles de redirección HTTPS, consulta: Qué hacer ante un bucle de redirección HTTPS en un sitio web en VPS.
Que el TTFB de la página de inicio sea normal no significa que los endpoints lo sean.
Lo que realmente va lento en muchos sitios es:
/api/search/wp-admin/admin-ajax.php/api/orders/graphql- Endpoint de inicio de sesión
- Páginas de listado del panel de administración
Pruébalos por separado:
curl -o /dev/null -s -w 'ttfb:%{time_starttransfer} total:%{time_total}\n' https://example.com/api/search
Si solo un endpoint va lento, no optimices todo el sitio a ciegas. Revisa ese endpoint directamente:
- Si consulta demasiado la base de datos
- Si llama a APIs externas
- Si no tiene caché
- Si hay espera de bloqueos
- Si está limitado por rate limiting o inspeccionado por WAF
Vi un sitio donde la página de inicio era rápida pero el endpoint de búsqueda tenía un TTFB de 6 segundos, y resultó que cada búsqueda hacía una petición en tiempo real a una API de terceros. Por muy caro que sea el VPS al que cambies, solo convertirás 6 segundos en 5,8 segundos.
Puedes seguir este orden:
# 1. 拆开 DNS、连接、TLS、TTFB、总耗时
curl -o /dev/null -s -w 'dns:%{time_namelookup}\nconnect:%{time_connect}\ntls:%{time_appconnect}\nttfb:%{time_starttransfer}\ntotal:%{time_total}\n' https://example.com/
# 2. 在 VPS 本机测源站
curl -o /dev/null -s -w 'ttfb:%{time_starttransfer} total:%{time_total}\n' http://127.0.0.1/
# 3. 绕过 CDN 测源站 IP
curl -H 'Host: example.com' -o /dev/null -s -w 'ttfb:%{time_starttransfer} total:%{time_total}\n' http://YOUR_ORIGIN_IP/
# 4. 看 Nginx 访问时间字段
tail -f /var/log/nginx/access_timing.log
# 5. 看应用日志
journalctl -u php8.2-fpm -n 100 --no-pager
# 6. 看系统资源
vmstat 1
iostat -xz 1
Luego juzga según los resultados:
| Síntoma | Qué revisar primero |
|---|---|
| DNS lento | Proveedor de DNS, ruta de resolución, red local |
| TLS lento | Cadena de certificados, redirecciones, modo SSL del CDN |
| El propio origen también va lento | Aplicación, PHP-FPM, base de datos, I/O |
| Origen rápido, CDN lento | Petición al origen del CDN, reglas de caché, WAF |
| upstream_response_time alto | Aplicación backend o base de datos |
| request_time alto pero upstream bajo | Nginx, cliente, descarga, limitación de velocidad |
| Un endpoint lento | Lógica del endpoint, SQL, APIs externas |
Un TTFB alto puede deberse, claro, a que la máquina es demasiado débil, pero no es la primera conclusión.
Casos en los que tiene sentido actualizar la máquina:
- CPU al máximo durante mucho tiempo
- Memoria insuficiente con swap frecuente
- I/O de disco al máximo durante mucho tiempo
- Base de datos ya optimizada pero recursos insuficientes
- Workers de PHP-FPM que siguen en cola tras una configuración razonable
Casos en los que actualizar no lo resuelve:
- Un plugin que escribe SQL lento
- Llamar a una API externa en cada petición
- Cloudflare que no cachea contenido estático
- Configuración incorrecta del proxy inverso de Nginx
- Cadena de redirecciones desordenada
- Base de datos sin índices
Actualizar el VPS a veces solo pospone el problema un mes. Lo que realmente deberías hacer es localizar primero en qué capa está la lentitud.
Si estás diagnosticando el TTFB de tu sitio web, aquí tienes algunos artículos para seguir leyendo:
- Qué hacer cuando WordPress va lento en un VPS
- Qué hacer ante 502 / 504 Bad Gateway en un VPS
- Qué hacer ante errores de configuración de Nginx en VPS
- Qué hacer cuando el I/O de disco del VPS es muy alto
- Qué hacer ante Cloudflare 521 / 522 en un sitio web en VPS
Por último, el criterio más práctico: si en curl el time_starttransfer es alto pero time_total no es mucho más alto que él, céntrate en el backend que genera la página; si time_starttransfer no es alto pero time_total sí lo es, céntrate en el tamaño de descarga, imágenes, ancho de banda y recursos del frontend. Distingue primero estas dos cosas y te ahorrarás la mayor parte de los rodeos.