Qué te dice realmente un 504
Un 504 dice que el proxy esperó a que WordPress respondiera, la respuesta no llegó dentro del presupuesto de tiempo, el proxy se rindió. La diferencia con 502 importa: 502 significa respuesta rota, 504 significa sin respuesta a tiempo.
La parte interesante es que los 504s usualmente tienen un culpable claro e identificable en algún lugar — una sola query lenta, un stall de API externa, un bucle descontrolado. Este playbook es cómo encontramos ese culpable cada vez.
La cadena de timeouts
Cada capa tiene su propio timeout. El 504 se origina en la capa con el timeout más corto que la petición subyacente excedió:
Cloudflare: 100s (free), 6000s (Enterprise)
Nginx fastcgi_read_timeout: 60s (default)
PHP max_execution_time: 30s (default)
MySQL max_execution_time: 0 (sin límite, default)Saber qué capa disparó primero acota el diagnóstico instantáneamente.
Causa 1 — Una petición PHP específica toma >30 segundos
El 504 más común. Una página en tu sitio WordPress genuinamente toma más que el max_execution_time de PHP para renderizarse.
Identificar la petición lenta
Habilita el slow log de PHP-FPM:
; /etc/php/8.1/fpm/pool.d/www.conf
slowlog = /var/log/php-fpm/www.slow.log
request_slowlog_timeout = 10sRecarga PHP-FPM. Reproduce el 504. Examina el slow log — nombrará el archivo y línea PHP exactos que corrían cuando el timeout golpeó.
Arreglo
Una vez que sabes el código lento: - Si es un plugin haciendo trabajo pesado en page load → muévelo a segundo plano (Action Scheduler, cron) - Si es una query de base de datos lenta → optimiza la query (añade índice, EXPLAIN, refactoriza) - Si es una llamada a API tercera → añade timeout wp_remote_request: 5s y fallback graceful
Para operaciones lentas inevitables (exports grandes), incrementa límites quirúrgicamente en lugar de globalmente:
// Solo al inicio del script lento
set_time_limit(300);
ini_set('memory_limit', '1G');Causa 2 — Query MySQL lenta
La query toma >30s. PHP espera, después expira.
Identificar
Habilita el slow query log de MySQL:
SET GLOBAL slow_query_log = 'ON';
SET GLOBAL long_query_time = 5;
SET GLOBAL slow_query_log_file = '/var/log/mysql/mysql-slow.log';Reproduce el 504. Examina el slow log.
Arreglo
- Añade índices — la mayoría de queries lentas de WordPress son escaneos de
wp_postmetasin índice en(post_id, meta_key) - Refactoriza la query — los arrays
meta_querya menudo producen SQL ineficiente; usatax_queryo tablas custom para queries pesadas - Cambia a caching — cachea el resultado con
wp_cache_seto transients
Causa 3 — Llamada HTTP externa dentro de petición PHP
Un plugin (contador de shares sociales, OEMBED, sync de Mailchimp) hace una llamada HTTP saliente. La API remota es lenta o inalcanzable. Tu petición PHP bloquea hasta que la llamada expira.
Identificar
En Query Monitor → HTTP API Calls, busca llamadas salientes durante page load. Tiempos en segundos = tu cuello de botella.
Arreglo
Configura timeouts sensatos para todas las llamadas wp_remote_*. La mayoría de plugins usan defaults de 30+ segundos.
$response = wp_remote_get($url, array(
'timeout' => 5,
));Para plugins que no controlas, puedes sobrescribir vía filtro:
add_filter('http_request_timeout', function($t) { return 5; });Causa 4 — Timeout duro de 100 segundos de Cloudflare
Aún con todo lo demás optimizado, el tier free/pro de Cloudflare tiene un timeout duro de 100 segundos en peticiones al origen. Operaciones admin de larga duración lo golpean.
Identificar
Ves la página 504 con marca Cloudflare (sus colores y logo). Revisa Cloudflare → Audit Logs por "origin connection timeout."
Arreglo
- Mueve operaciones largas a trabajos en segundo plano (siempre la respuesta correcta)
- Para operaciones solo-admin, bypasea Cloudflare en rutas
/wp-admin/(Page Rules → Cache Level: Bypass, Disable Performance) - Para clientes Enterprise, Cloudflare permite subir el timeout
No puedes subir el timeout en planes Free o Pro.
Causa 5 — Lock bloqueante en la base de datos
Una query de escritura de larga duración mantiene un lock. Las queries subsiguientes esperan, exceden el timeout. Las queries que esperan logean 504.
Identificar
SHOW PROCESSLIST;
SHOW ENGINE INNODB STATUS\GBusca queries en estado Locked o filas con WAITING FOR LOCK.
Arreglo
- Mata la query larga:
KILL <connection_id> - Investiga por qué una query toma tanto (usualmente un UPDATE en una columna no-indexada)
- Considera cambiar a
SET TRANSACTION ISOLATION LEVEL READ COMMITTEDpara queries de lectura que no necesitan locks
Causa 6 — Resolución DNS expirando
Una llamada HTTP saliente desde WordPress depende de DNS. El resolver DNS del servidor es lento o inalcanzable. La resolución sola toma 30s.
Identificar
dig +short api.someservice.com
time curl -v https://api.someservice.com/ 2>&1 | grep "Connected\|DNS"Si dig es lento o cuelga, esta es la causa.
Arreglo
Configura un resolver DNS rápido en el servidor:
# /etc/resolv.conf
nameserver 1.1.1.1
nameserver 8.8.8.8
options timeout:1 attempts:2O instala un resolver caching local (dnsmasq, unbound).
El flujo diagnóstico de 504
Cuando pase el próximo 504:
# Paso 1 — ¿cuándo pasó el 504?
date -d "@$(stat -c %Y /var/log/nginx/error.log)"
# Paso 2 — ¿qué corría en ese momento?
tail -200 /var/log/php-fpm/www.slow.log
# Paso 3 — ¿qué hacía MySQL?
grep -A 10 "Query_time" /var/log/mysql/mysql-slow.log | tail -50
# Paso 4 — ¿la llamada iba saliente?
tcpdump -i any port 443 -nn -c 50 2>/dev/null # mientras reproducesEsta secuencia encuentra el componente lento en menos de 10 minutos.
Errores comunes al diagnosticar 504
- Subir cada timeout a 600s — esconde el código lento, no lo arregla
- Reiniciar MySQL cuando una query está atascada — termina el lock holder pero la causa (query mala) vuelve la próxima
- Deshabilitar Cloudflare — deja el sitio desprotegido; el 504 era un síntoma no la causa
- "Solo actualiza el hosting" — la mayoría de 504s de WordPress lento tienen causa plugin o query, no causa servidor
Cuándo llamar a un especialista
Si has habilitado slow logs y el código ofensor está en un plugin que no puedes reemplazar fácilmente, hacemos este trabajo de reescritura/optimización rutinariamente. La mayoría de sitios WordPress propensos a 504 pueden arreglarse en 2-4 horas de profiling + optimización.
Soporte de emergencia 504 en minutos. Para problemas de rendimiento más amplios ve recuperación de velocidad WordPress.

