« 502 Bad Gateway » : ce message, affiché en pleine page blanche par nginx, ne dit rien de l’erreur PHP réelle, et pour cause : il n’y en a pas forcément. Un 502 signifie que nginx a bien transmis la requête au backend PHP-FPM, mais que celui-ci n’a jamais répondu dans le délai imparti, ou a fermé la connexion de façon anormale.
Ce type d’erreur apparaît typiquement lors d’un pic de trafic soudain : une campagne d’e-mailing bien ciblée, un article partagé massivement sur les réseaux, ou une simulation de charge lancée par une équipe marketing sans prévenir personne côté technique. Le site fonctionne parfaitement l’instant d’avant, puis une partie des visiteurs se met à voir des 502 par intermittence.
Comprendre où se situe la rupture
nginx et PHP-FPM communiquent via FastCGI, le plus souvent sur un socket Unix ou un port TCP local. Quand PHP-FPM ne répond pas assez vite, ou quand la connexion au socket échoue, nginx renvoie un 502 côté visiteur, tout en écrivant l’erreur précise dans son propre journal.
tail -f /var/log/nginx/error.log
# 2020/09/07 16:12:03 [error] 4821#4821: *892 upstream timed out
# (110: Connection timed out) while reading response header
# from upstream, client: 91.x.x.x, server: exemple.fr,
# request: "GET /boutique/ HTTP/1.1",
# upstream: "fastcgi://unix:/run/php/php7.4-fpm.sock:"
Cette ligne, à elle seule, confirme deux choses : le point de rupture se situe entre nginx et le socket PHP-FPM, et la cause est un délai d’attente dépassé, pas une erreur de syntaxe PHP.
Vérifier le pool PHP-FPM en parallèle

Le second journal à consulter est celui du pool PHP-FPM concerné, généralement dans /var/log/php7.4-fpm.log. Deux messages sont particulièrement révélateurs à ce stade :
server reached pm.max_children setting: tous les processus PHP disponibles sont occupés, les nouvelles requêtes attendent en file jusqu’au timeoutchild X exited on signal 9 (SIGKILL): un processus PHP a été tué, souvent par l’OOM killer du système, faute de mémoire disponible
Le premier cas oriente vers un dimensionnement insuffisant du pool par rapport au trafic réel. Le second oriente vers une limite mémoire du serveur, sujet différent qui demande de revoir la RAM allouée ou le nombre de processus autorisés.
Diagnostiquer le dimensionnement du pool
La formule de calcul classique consiste à diviser la mémoire disponible pour PHP-FPM par la consommation moyenne d’un processus PHP au repos, mesurée avec un outil comme ps ou via le statut FPM.
ps --no-headers -o "rss,cmd" -C php-fpm7.4 \
| awk '{ sum+=$1 } END { print sum/NR/1024 " Mo en moyenne" }'
Sur un serveur disposant de 4 Go dédiés à PHP-FPM, avec des processus consommant en moyenne 60 Mo, le plafond réaliste de pm.max_children tourne autour de 60, pas 200 comme on le voit parfois configuré par défaut sans réflexion.
Le correctif : pool et timeout ensemble
Deux réglages doivent être ajustés de concert dans le fichier de pool, souvent situé sous /etc/php/7.4/fpm/pool.d/www.conf :
pm = dynamic
pm.max_children = 60
pm.start_servers = 15
pm.min_spare_servers = 10
pm.max_spare_servers = 25
request_terminate_timeout = 60s
Côté nginx, le délai d’attente amont mérite aussi d’être vérifié, sans pour autant devenir la variable d’ajustement principale : l’augmenter sans corriger le dimensionnement du pool ne fait que retarder l’apparition du 502, pas le résoudre.
fastcgi_read_timeout 60s;
fastcgi_connect_timeout 10s;
Prévenir la récidive
Un pool PHP-FPM correctement dimensionné pour le trafic habituel doit pouvoir absorber un pic ponctuel sans passer en 502 ; s’il faut relever le timeout pour tenir, c’est le signe que le vrai correctif se trouve ailleurs.
La supervision du statut FPM (pm.status_path activé et surveillé) permet de détecter la saturation du pool avant qu’elle ne se traduise en erreurs visibles côté visiteur, en observant l’évolution du nombre de processus actifs et de la file d’attente au fil du temps.
En résumé
Un 502 Bad Gateway entre nginx et PHP-FPM se diagnostique en croisant deux journaux : celui de nginx, qui révèle la nature du timeout, et celui du pool PHP-FPM, qui révèle sa cause réelle, saturation ou manque de mémoire. Le correctif durable passe presque toujours par un redimensionnement raisonné du pool en fonction de la mémoire réellement disponible, bien avant de toucher aux délais d’attente qui ne font que masquer le symptôme.