Logo
WP Fix by Blimx

WordPress 504 Gateway Timeout — Playbook Definitivo

Actualizado:
ErrorsPerformance

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 = 10s

Recarga 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_postmeta sin índice en (post_id, meta_key)
  • Refactoriza la query — los arrays meta_query a menudo producen SQL ineficiente; usa tax_query o tablas custom para queries pesadas
  • Cambia a caching — cachea el resultado con wp_cache_set o 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\G

Busca 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 COMMITTED para 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:2

O 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 reproduces

Esta 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.