
Votre site affiche 504 Gateway Time-out. Parfois partout, parfois sur la seule page de connexion, parfois quelques minutes par jour à heure fixe.
Une question commande tout le reste, et il vaut mieux la trancher avant de toucher au moindre réglage : à l'instant où la requête a été coupée, est-ce que PHP attendait quelque chose, ou est-ce qu'il calculait ? Les deux cas ne donnent pas le même code et ne se réparent pas au même endroit. Le conseil que vous allez lire partout ne vaut que pour le second, et un 504 relève presque toujours du premier.
PHP attendait, ou PHP calculait
Une requête WordPress qui traîne le fait pour l'une de deux raisons, et elles n'ont rien de commun.
Elle attend : une requête SQL qui ne revient pas, une API distante muette, un disque saturé, une couche placée devant qui met du temps à transmettre. Le processus PHP est bien vivant, il ne fait rien, il patiente.
Elle calcule : un import, une régénération de miniatures, une requête WooCommerce sur un catalogue trop gros. Le processus consomme du temps machine sans interruption.
max_execution_time, la limite dont parlent tous les articles, ne compte que le temps de calcul. Le temps d'attente lui échappe. Notre banc d'essai le vérifie : un WordPress, un PHP-FPM avec max_execution_time à 30 secondes, deux serveurs web branchés dessus en parallèle, et deux pages de test qui durent aussi longtemps l'une que l'autre.
- la page qui attend 90 secondes répond 200 au bout de 90 secondes sous Apache. La limite des 30 secondes n'a jamais été atteinte, PHP ne l'a pas vue passer.
- la page qui calcule est tuée à 30,03 secondes et renvoie 500 avec un corps vide, zéro octet. Pas un 504.
Le tri se fait donc tout seul, sur ce que vous avez à l'écran. Un 504 signifie que PHP attendait et que quelqu'un d'autre a raccroché, le serveur web ou un proxy devant lui : le réglage en cause est le sien. Une page blanche avec un code 500 et rien dedans signifie l'inverse, PHP calculait et s'est fait tuer par sa propre limite. C'est alors le guide de l'erreur 500 qui prend le relais, et max_execution_time y est bien le bon réglage.
L'avertissement principal de cette page tient là : augmenter max_execution_time ne répare presque jamais un 504. Nous avons dépouillé vingt et une pages sur huit marchés, en sept langues. Toutes donnent ce conseil, aucune ne fait la distinction.
Ce que l'écran vous dit avant votre hébergeur
Trois pages de 504 circulent, elles ne se ressemblent pas, et chacune désigne son émetteur.

nginx écrit une page de 176 octets : un titre 504 Gateway Time-out, un filet, une signature du type nginx/1.24.0 (Ubuntu). Son code source porte en plus des lignes de remplissage invisibles à l'écran, ajoutées pour dépasser les 512 octets sous lesquels certains navigateurs substituent leur propre page. Quand elles apparaissent dans le message « La mise à jour a échoué » de votre tableau de bord, vous savez qui a répondu. Certains mutualisés signent openresty : c'est encore du nginx, sous un autre nom.

Apache écrit une page de 338 octets, titrée Gateway Timeout, avec la phrase « The gateway did not receive a timely response from the upstream server or application » et sa signature Apache/2.4.58 Server at.
Cloudflare affiche une page habillée à ses couleurs, et c'est là que se joue le tri le plus utile de ce guide. Sa documentation dit deux choses que le corpus ne reprend jamais. Quand c'est Cloudflare qui abandonne l'attente, il n'écrit pas un 504 mais une erreur 524 : son délai de lecture vaut 125 secondes et n'est modifiable que sur son offre la plus haute. Et une page 504 habillée à ses couleurs signifie que le serveur d'origine a bien répondu 504, Cloudflare s'étant contenté de relayer. C'est l'inverse de ce que suppose le lecteur, qui accuse la couche placée devant alors que la panne est chez lui.
Un dernier cas, relevé sur un forum et jamais élucidé pour celui qui le vivait : sa page d'erreur portait la signature nginx/1.23.2 alors que son hébergeur, vérification faite, ne sert qu'en Apache. Une signature qui ne correspond pas à votre pile prouve qu'une couche existe devant, et que vos journaux resteront vides.
En trente secondes
Relevez le code, le poids et la durée, depuis n'importe quel terminal :
curl -s -o /dev/null \
-w "%{http_code} %{size_download} %{time_total}\n" \
https://votre-site.fr/
Le troisième nombre est celui qui compte. Un délai de coupure est presque toujours une valeur ronde : 30, 60, 120, 300 secondes. Il désigne à lui seul la directive à aller chercher, et il évite d'en modifier quatre au hasard.
Vérifiez si le site public tient debout pendant que la connexion tombe. Cette asymétrie est le cas le plus fréquent du sujet, et son diagnostic ne ressemble à aucun autre.
Notez l'heure à la seconde, avant de recharger. C'est ce qui rend une ligne de journal trouvable, par vous ou par le support.
La même panne, un code différent selon le serveur
En ajoutant les mesures du 504 à celles déjà publiées sur le 502 et le 503, la famille est complète. Même PHP, même site, deux serveurs web interrogés dans la même seconde.
| ce qui se passe | Apache 2.4 avec proxy_fcgi |
nginx 1.24 avec fastcgi_pass |
|---|---|---|
| PHP est arrêté | 503, 390 o | 502, 166 o |
| PHP attend, 90 s | 200 au bout de 90 s | 504 à 60,06 s, 176 o |
| PHP attend, 340 s | 504 à 300,04 s, 338 o | 504 à 60 s |
PHP calcule au-delà de max_execution_time |
500, corps vide, à 30,03 s | idem |
PHP tué par request_terminate_timeout |
503, 390 o | non mesuré |
La deuxième ligne fait perdre le plus de temps. La même page lente donne un 504 sur nginx et un 200 sur Apache, parce que nginx abandonne à 60 secondes quand la configuration Apache de notre banc attendait jusqu'à 300. Poussée à 340 secondes, l'attente finit bien par produire un 504 sous Apache aussi, à 300,04 secondes exactement.
Beaucoup de sites français sont servis en Apache, chez OVH comme chez o2switch. Un 504 qui tombe au bout d'une minute sur une telle pile ne vient donc pas du serveur web mais d'une couche placée devant. Et si le code sous vos yeux est un 502 ou un 503, ce sont d'autres gestes et un autre premier tri : le guide de l'erreur 502 traite le PHP qui ne répond pas du tout, celui de l'erreur 503 le service déclaré indisponible.
Quelle directive coupe, et laquelle gagne
Le corpus se contredit ici. Les uns nomment ProxyTimeout, les autres Timeout, personne ne dit ce qui se passe quand les deux sont là. Nous avons mesuré les combinaisons sur le même banc.
| configuration Apache | résultat |
|---|---|
Timeout 300, pas de ProxyTimeout, attente de 60 s |
200, rien ne coupe |
Timeout 300, pas de ProxyTimeout, attente de 340 s |
504 à 300,04 s |
ProxyTimeout 15 |
504 à 15,02 s |
Timeout 20, pas de ProxyTimeout |
504 à 20,01 s |
Timeout 20 et ProxyTimeout 45 |
504 à 45,04 s |
La règle tient en une phrase : Timeout s'applique par défaut, ProxyTimeout le remplace dès qu'il est présent. La dernière ligne le montre sans ambiguïté, la coupure arrive à 45 secondes et pas à 20. Regarder l'une sans l'autre fait chercher pendant une heure une valeur qui n'est jamais appliquée.
Côté nginx, la directive qui coupe s'appelle fastcgi_read_timeout, son défaut est de 60 secondes, et nous l'avons mesurée à 60,06. Aucune page française du sujet ne la nomme. Les articles recopient proxy_read_timeout, proxy_send_timeout et proxy_connect_timeout, qui gouvernent un autre mode de transmission : sur une pile WordPress ordinaire, où nginx parle à PHP-FPM par fastcgi_pass, ce sont les directives fastcgi_* qui décident. Un utilisateur derrière un proxy nginx a porté les cinq délais recopiés partout à 300 secondes sur chacun de ses domaines, et son 504 de connexion n'a pas bougé d'une seconde.
Sur beaucoup de mutualisés, ces valeurs sont figées. Un lecteur raconte un max_execution_time bloqué à 90 secondes par son hébergeur, alors que la mise à jour de son thème en réclamait 180. Quand le réglage est hors de portée, la sortie consiste à raccourcir le travail : lancer la tâche en SSH avec WP-CLI, ou la découper en lots.
Le délai côté PHP-FPM, qui transforme le 504 en 503
Voilà le piège qui égare le plus de diagnostics, et aucune page du sujet ne le mentionne.
PHP-FPM a son propre délai, request_terminate_timeout, réglé dans le fichier du pool. Posé à 25 secondes sur une attente de 60, il ne produit pas un 504 mais un 503 de 390 octets, la même page qu'un pool complètement arrêté, et elle arrive à 31,3 secondes et non à 25 : FPM vérifie ses processus par intervalles. Si votre hébergeur a posé cette directive, votre panne de délai s'affiche donc sous un code qui vous enverra chercher ailleurs.
Le journal, lui, ne ment pas :
WARNING: [pool www] child 3715, script '/var/www/site/lent.php'
(request: "GET /lent.php?s=60") execution timed out (31.323814 sec), terminating
WARNING: [pool www] child 3715 exited on signal 15 (SIGTERM) after 33.340654 seconds

C'est la seule ligne de tout le système qui nomme le script fautif. Ni le journal du serveur web, ni debug.log, ni l'écran d'erreur ne le donnent. Sur un 504, c'est là qu'il faut regarder en premier.
Côté serveur web, la ligne est différente. Sous nginx, dans error.log :
upstream timed out (110: Connection timed out)
while reading response header from upstream,
client: 183.xx.xx.xxx, request: "GET /wp-admin/ HTTP/2.0",
upstream: "fastcgi://unix:/run/php/php8.3-fpm.sock"
Elle donne l'URL coupée et la socket visée, ce qui suffit souvent à cerner le déclencheur.
Où sont ces journaux. Sur un serveur que vous administrez, /var/log/nginx/error.log ou /var/log/apache2/error.log, et /var/log/php8.3-fpm.log pour PHP-FPM, le numéro suivant votre version. En cPanel, un fichier error_log apparaît dans le dossier où l'erreur s'est produite. En Plesk, /var/www/vhosts/votre-domaine.fr/logs/. Chez OVH en mutualisé, ils vivent sur un espace de logs séparé, hors du FTP du site, un fichier par jour. Ailleurs, cherchez un dossier logs à côté de la racine et non dedans. Avec un accès SSH :
grep -i "timed out" /var/log/php8.3-fpm.log | tail -n 20
Une précision qui économise une soirée : activer WP_DEBUG ne montrera rien. Un 504 n'est pas une erreur PHP, c'est une requête trop longue. Le fichier debug.log restera vide, et ce vide est une information, pas une panne du journal.
Ce qui déclenche vraiment un 504
Ce classement vient de dix-neuf fils de discussion publics lus en entier, réponses comprises, et non de la liste de causes que les articles se recopient.
La connexion à wp-admin, site public intact. Cinq fils, le groupe le plus fourni. Il a sa section plus bas.
Une action longue lancée depuis le tableau de bord. Cinq fils également. En tête, la mise à jour ou l'installation d'une extension. Puis la réparation ou l'optimisation de la base, ce qui ne manque pas de sel : « réparer la base » est justement la solution que huit pages du corpus proposent contre le 504. Puis la mise à jour automatique du cœur, avec un cas daté à la minute près où les 504 commencent aussitôt après le passage en 6.7.2.
Une saturation de fond. Cinq fils encore. Mutualisé revendu au-delà de ses capacités, voisin bruyant sur la même machine, ou trafic de robots. Dans un cas, le support a identifié un processeur à 100 % causé par des robots, et la réponse retenue a été de placer Cloudflare devant le site : le geste marche souvent, mais il ajoute une couche qui produira ses propres 524.
Le reste se répartit entre une URL unique toujours la même, un incident chez l'hébergeur, et une pile qui se dégrade lentement. Ce qui n'apparaît pas mérite aussi d'être dit : l'import d'un gros fichier, que le corpus professionnel cite plus que tout le reste, ne figure pas une seule fois dans les dix-neuf fils.
Le 504 qui ne frappe que le tableau de bord
C'est le cas le plus courant des forums, et aucune page du top 10, sur aucun des huit marchés dépouillés, ne le traite. Les gens le décrivent tous de la même façon :
Website is working fine, but getting « 504 Gateway Timeout » error when trying to login.
It is when I click « Log In » that the timeout occurs. The timeout error appears after one minute.
Le second témoignage date de 2017. Cinq ans plus tard, quelqu'un est venu écrire sous le fil qu'il avait le même symptôme, et demander ce qui l'avait résolu. Personne n'a répondu.
Le mécanisme le plus probable a été énoncé une seule fois dans tout ce que nous avons lu : « If your site is only online because of caching you'll get 504s. Logging in is an un-cached request. » Votre site public est servi depuis un cache de page, sans jamais réveiller PHP, et il tient donc debout. La connexion n'est jamais mise en cache : c'est la seule requête qui sollicite encore PHP, et c'est la seule qui tombe.
Nous n'avons pas reproduit ce cas sur notre banc, faute d'y avoir installé un cache de page. C'est donc l'explication la plus cohérente avec tout ce qui précède, pas une mesure. Vérifiez-la vous-même, elle tient en deux commandes :
curl -s -o /dev/null -w "%{time_starttransfer}\n" https://votre-site.fr/
curl -s -o /dev/null -w "%{time_starttransfer}\n" https://votre-site.fr/wp-login.php
Si la première rend quelques centièmes de seconde et la seconde plusieurs secondes, la démonstration est faite : votre page d'accueil ne passe plus par PHP, votre page de connexion si, et c'est PHP qui va mal. La méthode complète, avec le piège du fichier témoin qui fausse la mesure, est détaillée dans le guide du site WordPress devenu très lent.
Inutile, dans ce cas, de désactiver les extensions à l'aveugle : la panne dépend de la charge et du temps, pas d'un fichier fautif. Cherchez plutôt combien de processus PHP vous avez, ce qui les occupe, et ce qui rend une requête non mise en cache aussi lente.
Trois adresses qui consomment sans qu'on les voie
admin-ajax.php est le point d'entrée par lequel WordPress travaille en arrière-plan pendant que vous regardez une page, et chaque appel occupe un processus PHP pendant toute sa durée. Pour le repérer, ouvrez l'onglet Réseau du navigateur avec le filtre XHR et chargez une page publique en étant déconnecté : si ce fichier apparaît, ses paramètres nomment presque toujours l'extension responsable.
xmlrpc.php accepte plusieurs actions dans une seule requête, ce qui en fait une cible classique des tentatives de connexion automatisées, et chaque appel démarre WordPress en entier. Des rafales dans votre journal d'accès vous disent ce qui remplit vos processus.
Le sitemap généré à la volée est le cas le plus spectaculaire. Un fil de février 2026 décrit une boutique d'un million de produits dont le plan de site est calculé par PHP et par la base à chaque appel, avec des 504 à chaque passage de Googlebot. Une seule URL tombe, toujours la même, et la panne se découvre le plus souvent dans la Search Console. Le remède consiste à sortir WordPress du chemin critique : produire des fichiers XML physiques par lots, sous les 50 000 URL et les 50 Mo réglementaires, et les servir tels quels.
Si rien n'a marché
Le 504 est généralisé et le panneau de votre hébergeur est lui aussi injoignable. L'incident est chez lui, cherchez sa page d'état avant tout le reste. Un fil documente une coupure de plusieurs jours pendant laquelle des hébergeurs avaient fermé les accès d'administration en attendant un correctif de sécurité. Ne restaurez surtout pas une sauvegarde tant que le serveur n'est pas rétabli.
Le 504 s'affiche quelques secondes avant une erreur de connexion à la base. Ce n'est plus un problème de délai mais un serveur de base de données qui ne suit plus.
Ce que nous ne faisons pas. Le forfait couvre la panne : remettre le site en ligne et vous dire ce qui l'a causé. Il ne couvre ni la reconstruction d'une mise en page abîmée dans un constructeur, ni la refonte d'un thème.
Si vous en êtes à comparer des valeurs de Timeout dans une configuration que vous n'avez pas écrite, l'intervention coûte moins cher que la soirée. On peut remettre en marche un site WordPress qui expire pour 149 € HT, remis en ligne ou remboursé.
Comment éviter que ça recommence
Mesurez vos deux temps de première réponse à froid. Les commandes curl données plus haut, lancées un jour où tout va bien, vous donnent votre référence. Sans elle, vous ne saurez pas dire si trois secondes sont une dégradation ou votre ordinaire.
Ne lancez plus les traitements longs depuis le tableau de bord. Import, régénération de miniatures, optimisation de base, sauvegarde complète : chacun est une requête HTTP avec un délai au-dessus de la tête. En SSH, il n'y en a aucun.
Ne mettez pas quarante extensions à jour dans la même minute. Un cas documenté ajoute un détail que personne ne relève : le site en question avait laissé WP_DEBUG_LOG actif et son thème écrivait un avertissement PHP à chaque appel, si bien que le journal avait dépassé le gigaoctet et que chaque mise à jour y écrivait encore. Surveillez la taille de wp-content/debug.log.
Vérifiez que votre cache de page fonctionne réellement, et que la connexion et le tableau de bord en sont exclus. Un cache qui s'arrête sans que personne s'en aperçoive transforme un site confortable en site qui expire, du jour au lendemain, sans qu'une ligne ait été modifiée.
Repérez vos journaux maintenant, site en état de marche. Savoir où votre hébergeur expose error_log et le journal de PHP-FPM vaut une heure le jour où ça tombe.
Questions fréquentes
C'est quoi l'erreur 504 ?
Un code de réponse HTTP qui signifie qu'un serveur intermédiaire a transmis votre demande à un autre service et n'a pas obtenu de réponse dans le délai qu'il s'était fixé. Sur un WordPress, ce service est PHP. Le code ne dit pas pourquoi PHP a été long, seulement qu'un autre a raccroché à sa place.
Comment résoudre le problème 504 Gateway Time-out ?
Relevez d'abord la durée exacte avant la coupure, avec curl -s -o /dev/null -w "%{time_total}\n". Cette valeur désigne la directive en cause : fastcgi_read_timeout sous nginx, Timeout ou ProxyTimeout sous Apache, request_terminate_timeout côté PHP-FPM. Ouvrez ensuite le journal de PHP-FPM, le seul qui nomme le script fautif. Un réglage n'a de sens qu'une fois la requête longue identifiée, et la bonne réparation consiste le plus souvent à raccourcir le travail, pas à allonger l'attente.
Faut-il augmenter max_execution_time pour corriger un 504 ?
Presque jamais, et c'est pourtant le conseil que donnent toutes les pages du sujet. Cette limite ne compte que le temps de calcul de PHP, pas son temps d'attente. Nous avons mesuré une page qui attend 90 secondes avec une limite fixée à 30 : elle répond 200 au bout de 90 secondes, la limite n'entre jamais en jeu. Quand PHP calcule vraiment trop longtemps, il est tué par cette limite et renvoie un 500 avec un corps vide, pas un 504.
C'est quoi 504 Gateway Time-out nginx ?
C'est nginx qui vous parle. Sa page d'erreur pèse 176 octets et porte sa signature de version en pied. Sur une pile WordPress, la directive qui produit ce message est fastcgi_read_timeout, dont le défaut est de 60 secondes, mesuré sur notre banc à 60,06. Les proxy_read_timeout et consorts que recopient les articles français gouvernent un autre mode de transmission et ne changeront rien.
Erreur 504 ou erreur 524, comment les distinguer ?
Le 524 est propre à Cloudflare et signifie que son propre délai de lecture, 125 secondes par défaut, a été dépassé. Le 504 vient de votre pile. Le point contre-intuitif est qu'une page 504 habillée aux couleurs de Cloudflare indique que votre serveur d'origine a bien répondu 504 et que Cloudflare a simplement transmis. Pour lever le doute, regardez les en-têtes de la réponse : server: dit qui a écrit la page, cf-ray: dit qu'elle est passée par Cloudflare.
J'ai un 504 chez OVH ou o2switch, est-ce que ce guide s'applique ?
Oui, avec une précision qui vous fera gagner du temps. Ces hébergeurs servent en Apache, où c'est Timeout ou ProxyTimeout qui coupe, et nous avons mesuré une attente de 90 secondes qui passe sans encombre sur une configuration Apache courante. Un 504 qui arrive au bout d'une minute sur cette pile vient donc d'une couche placée devant, pas du serveur web. Vérifiez la signature de la page avant de toucher à votre configuration.