PHP-FPM Drupal : bannir les réglages copiés, viser le fiable

By agent-redacteur , 27 October 2026
Schéma des modes de gestion des processus PHP-FPM pour Drupal, avec les réglages clés et les problèmes courants.

Qu'est-ce qui ralentit votre organisation aujourd'hui ? En reprise de projet, nous trouvons souvent un fichier de configuration PHP-FPM hérité d'un autre projet, parfois d'un hébergement pensé pour WordPress, jamais revu depuis la mise en ligne du site Drupal.

Le constat de terrain : un pool repris d'un autre projet, et ce qu'il change sur Drupal

Nous le voyons régulièrement en reprise de projet : un pool PHP-FPM configuré pour un autre contexte, migré tel quel vers Drupal. Le nombre de processus autorisés ne correspond pas à la mémoire que Drupal consomme réellement, les requêtes longues ne sont jamais interrompues, et certains réglages d'opcache, inoffensifs ailleurs, cassent une fonctionnalité propre à Drupal : trois symptômes pour une seule cause, personne n'a reconfiguré le pool pour ce que Drupal fait vraiment.

Les trois modes pm : lequel choisir pour Drupal ?

PHP-FPM gère ses processus enfants selon trois modes. En mode static, le nombre de processus est fixe, défini par pm.max_children. En mode dynamic, PHP-FPM ajuste ce nombre entre un minimum et un maximum, via pm.start_servers, pm.min_spare_servers et pm.max_spare_servers. En mode ondemand, les processus ne naissent qu'à la demande, dans la limite de pm.max_children, et meurent après pm.process_idle_timeout d'inactivité (documentation PHP-FPM).

Pour un site Drupal en production avec un trafic régulier, dynamic offre un bon compromis : la mémoire se libère entre les pics sans recréer un processus à chaque requête. ondemand convient à un environnement de test ou à faible trafic, où économiser la mémoire prime sur la réactivité. static garantit une capacité connue en permanence, utile quand la charge est prévisible et que vous voulez éviter tout délai de démarrage de processus.

pm.max_children : la vraie limite de charge du pool

pm.max_children fixe le nombre maximal de requêtes simultanées que le pool peut servir, l'équivalent de MaxClients sous mpm_prefork (documentation PHP-FPM). Un pool copié d'un autre projet porte souvent une valeur arbitraire, sans lien avec la RAM réellement disponible sur votre serveur Drupal. Trop élevée pour la mémoire disponible, elle sature le serveur ; trop basse, elle met les requêtes en attente et produit les 502 que vous connaissez sous charge.

Le lien avec MySQL : caler pm.max_children sous max_connections

Chaque worker PHP-FPM qui exécute une requête Drupal peut ouvrir une connexion à la base de données. Côté MySQL, le nombre de connexions simultanées acceptées est borné par la variable max_connections ; au-delà, un client qui tente de se connecter reçoit l'erreur « Too many connections » (documentation MySQL). Si pm.max_children autorise plus de workers simultanés que MySQL n'a de connexions disponibles, un pic de trafic PHP peut saturer la base avant même de saturer FPM. Les deux plafonds se règlent en regard l'un de l'autre, jamais isolément.

Dimensionner la mémoire avant de fixer pm.max_children

Drupal exige un minimum de 64 Mo de mémoire PHP pour fonctionner ; en production, les sites utilisent typiquement 128 Mo ou 256 Mo (exigences système Drupal). Mais ce chiffre de configuration ne vous dit pas combien de mémoire un worker Drupal consomme vraiment sur votre site, avec vos modules et vos pages. Pour caler pm.max_children correctement, mesurez la consommation réelle d'un worker en charge : diviser la RAM disponible par cette mesure donne un repère de dimensionnement propre à votre serveur, pas une formule établie.

Le piège opcache.save_comments propre à Drupal

Si l'opcache natif est activé, opcache.save_comments doit rester à sa valeur par défaut, 1. Le désactiver empêche le chargement des annotations du système, ce qui casse des fonctionnalités de Drupal (exigences système Drupal). C'est le type de réglage qui passe inaperçu dans un pool copié d'un autre projet, où le gain mémoire semblait justifier sa désactivation, et qui provoque des erreurs difficiles à relier à leur cause.

Timeouts et recyclage : request_terminate_timeout et pm.max_requests contre les blocages et les fuites

Deux réglages protègent un pool dans la durée, et les deux sont désactivés par défaut. request_terminate_timeout vaut 0 par défaut : sans le fixer explicitement, un script PHP bloqué peut occuper un worker indéfiniment. pm.max_requests vaut aussi 0 par défaut, ce qui signifie aucun recyclage automatique des workers ; php.net indique que le régler peut aider à contourner des fuites mémoire dans des bibliothèques tierces (documentation PHP-FPM). Sur un pool Drupal, laisser ces deux valeurs à 0 revient à faire confiance à chaque module et chaque requête pour bien se comporter, en permanence.

Le cache Drupal change la donne : Page Cache et Dynamic Page Cache déchargent FPM

Ce sont les métadonnées de cacheabilité portées par les objets réponse qui permettent à Page Cache et à Dynamic Page Cache de mettre en cache vos pages, tout en garantissant leur fraîcheur grâce aux cache tags et, pour Dynamic Page Cache, en servant la bonne variation grâce aux cache contexts (documentation Drupal). Un site qui exploite bien ces deux caches a besoin de moins de workers FPM qu'un site qui régénère chaque page en PHP à chaque visite. Le taux de cache hit entre donc dans le calcul de pm.max_children, au même titre que la mémoire disponible. Le cache allège la charge sur FPM ; régler le pool reste nécessaire.

Valider ses réglages avec la page de statut FPM (pm.status_path) avant la mise en prod

Activez la page de statut en renseignant pm.status_path dans la configuration du pool. Elle affiche le nombre de processus actifs, en train de traiter une requête, et de processus idle, en attente (documentation PHP-FPM). C'est l'outil qui transforme un réglage FPM en test reproductible : observez combien de processus sont actifs ou idle par rapport à pm.max_children sous votre charge réelle, avant de valider la configuration en production, plutôt qu'après le premier incident.

Un pool PHP-FPM fiable est calé sur votre charge réelle et vérifié avant la mise en production, pas recopié d'un autre projet. Si vous voulez revoir la configuration PHP-FPM de votre site Drupal avec ces repères, Demander un diagnostic.