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 PROCESSLISTmontre la requête encore en cours au moment du 504. - PHP autorisé à durer plus longtemps que Nginx.
max_execution_timeà 120 secondes etfastcgi_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é
- Notez l’URL et l’heure du 504.
- 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.
- 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.
- 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.
- 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
| Constat | Correction |
|---|---|
| Requête SQL longue | Index ou requête réécrite. Le délai du proxy ne répare pas le plan d’exécution |
| PHP plus long que le proxy | Faire échouer PHP avant le proxy, avec un message contrôlé, ou accélérer la page |
| API externe bloquante | Délai court sur cet appel, et reprise en file si le travail peut attendre |
| Export dans le navigateur | Le sortir vers une tâche de fond. La page ne fait qu’enregistrer la demande |
| File d’attente PHP-FPM | Augmenter 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.
