Retour au blog Monitoring - 7 min

Erreur 504 Gateway Timeout : les causes les plus fréquentes

Le 504 signifie que le proxy a attendu l’amont trop longtemps. Sortez la requête lente du cycle web au lieu d’allonger tous les délais.

Le code 504 Gateway Timeout signifie que le serveur, agissant comme passerelle ou proxy, n’a pas reçu à temps une réponse de l’amont qu’il a contacté. La connexion vers PHP, l’autre serveur ou l’API a bien commencé. Le délai du proxy (proxy_read_timeout, fastcgi_read_timeout) expire avant la fin de la réponse. Le visiteur reçoit 504. L’amont, lui, travaille parfois encore.

Ce n’est pas un 408 : là, le serveur attendait les octets du client. Ici, le proxy attend l’application.

Causes de lenteur qui finissent en 504

  • Une requête SQL plus longue que le délai du proxy. Index absent, jointure sur un catalogue entier, ou verrou qui bloque une écriture de commande. SHOW PROCESSLIST montre la requête encore en cours au moment du 504.
  • PHP autorisé à durer plus longtemps que Nginx. max_execution_time à 120 secondes et fastcgi_read_timeout à 60 : le proxy abandonne, PHP continue, puis écrit un 200 que personne ne voit.
  • Un appel sortant dans la page : ERP, transporteur, outil d’e-mailing. Le site attend cette API sans délai propre, et le proxy coupe le premier.
  • Un export, un PDF ou une sauvegarde lancés dans la requête HTTP du navigateur. Le travail n’a pas sa place dans le cycle d’une page.
  • Un pool PHP-FPM saturé. Les requêtes font la queue plus longtemps que le délai du proxy, même si chacune serait rapide seule. Le symptôme ressemble à une lenteur générale, pas à une seule URL.

Prouver que le délai est dépassé

  1. Notez l’URL et l’heure du 504.
  2. Dans le journal Nginx, cherchez « upstream timed out ». Si la phrase parle d’une connexion fermée ou d’une réponse vide, vous êtes sur un 502.
  3. Au même instant, regardez la liste des requêtes MySQL et le journal lent de PHP-FPM. Une requête encore active après le 504 confirme que l’amont n’avait pas fini.
  4. Comparez les délais : celui du proxy doit être connu, celui de PHP aussi. S’ils ne sont pas dans le même ordre, vous expliquerez les 200 tardifs.
  5. Mesurez l’URL depuis l’extérieur avec un test d’URL. Un 504 répété n’est pas un caprice du navigateur.

Une maintenance annoncée ne doit pas produire ce code. Elle se publie en 503 avec Retry-After, avec une fin prévue. Un 504, lui, n’annonce aucune reprise.

Raccourcir le travail

ConstatCorrection
Requête SQL longueIndex ou requête réécrite. Le délai du proxy ne répare pas le plan d’exécution
PHP plus long que le proxyFaire échouer PHP avant le proxy, avec un message contrôlé, ou accélérer la page
API externe bloquanteDélai court sur cet appel, et reprise en file si le travail peut attendre
Export dans le navigateurLe sortir vers une tâche de fond. La page ne fait qu’enregistrer la demande
File d’attente PHP-FPMAugmenter les workers seulement si la machine a la mémoire. Sinon, réduire le travail simultané

Aligner les délais veut dire que le visiteur reçoit une erreur claire de l’application avant que le proxy ne coupe, pas que toutes les couches attendent cinq minutes.

Ce qu’il ne faut pas faire

Ne montez pas tous les timeouts « par sécurité ». Les workers restent occupés et le 504 revient sous charge. Ne redémarrez pas le serveur en boucle : la requête lente est relancée par les visiteurs qui actualisent. Ne confondez pas avec un 408, qui se corrige du côté de la lecture du client. Ne jugez pas la santé du site sur la seule page d’accueil en cache : l’URL lente peut être la seule en 504.

Après correction, l’URL doit répondre dans un délai inférieur à celui du proxy, y compris depuis un réseau extérieur. C’est le critère de test de disponibilité appliqué à une page qui expirait.

Questions fréquentes

Quelle est la différence entre un 502 et un 504 ?

Le 502 signifie que l’amont a répondu quelque chose d’inutilisable. Le 504 signifie que le proxy n’a pas reçu de réponse complète avant son délai, alors que la connexion vers l’amont avait été établie.

Pourquoi la page finit parfois par s’afficher après le 504 ?

PHP continue après que Nginx a abandonné. Le visiteur a déjà reçu le 504, puis le journal d’accès de l’application montre un 200 tardif. Les deux délais ne sont pas alignés.

Mettre proxy_read_timeout à 300 secondes règle-t-il le problème ?

Cela masque une requête qui ne devrait pas durer autant. Le worker reste occupé, et le prochain pic reproduira le 504. Il faut raccourcir le travail.

Surveiller mes URL