{"id":16053,"date":"2025-12-20T11:51:36","date_gmt":"2025-12-20T10:51:36","guid":{"rendered":"https:\/\/webhosting.de\/php-fpm-prozess-management-pm-max-children-optimieren-core\/"},"modified":"2025-12-20T11:51:36","modified_gmt":"2025-12-20T10:51:36","slug":"php-fpm-gestion-des-processus-pm-max-children-optimiser-core","status":"publish","type":"post","link":"https:\/\/webhosting.de\/fr\/php-fpm-prozess-management-pm-max-children-optimieren-core\/","title":{"rendered":"Configurer correctement la gestion des processus PHP-FPM : pm.max_children &amp; Co. expliqu\u00e9"},"content":{"rendered":"<p><strong>R\u00e9glage php-fpm<\/strong> d\u00e9termine le nombre de processus PHP-FPM pouvant \u00eatre ex\u00e9cut\u00e9s simultan\u00e9ment, la vitesse \u00e0 laquelle les nouveaux processus d\u00e9marrent et la dur\u00e9e pendant laquelle ils traitent les requ\u00eates. Je vais vous montrer comment <strong>pm.max_children<\/strong>, pm, pm.start_servers, pm.min_spare_servers, pm.max_spare_servers et pm.max_requests de mani\u00e8re \u00e0 ce que votre application r\u00e9agisse rapidement sous la charge et que le serveur ne bascule pas en mode swapping.<\/p>\n\n<h2>Points centraux<\/h2>\n\n<ul>\n  <li><strong>mode pm<\/strong>: choisissez correctement entre static, dynamic ou ondemand afin que les processus soient adapt\u00e9s \u00e0 votre trafic.<\/li>\n  <li><strong>pm.max_children<\/strong>: aligner le nombre de processus PHP simultan\u00e9s sur la RAM et la consommation r\u00e9elle du processus.<\/li>\n  <li><strong>Valeurs de d\u00e9marrage\/de r\u00e9serve<\/strong>: pm.start_servers, pm.min_spare_servers, pm.max_spare_servers \u00e9quilibrer de mani\u00e8re judicieuse.<\/li>\n  <li><strong>recyclage<\/strong>: Att\u00e9nuer les fuites de m\u00e9moire avec pm.max_requests sans g\u00e9n\u00e9rer de surcharge inutile.<\/li>\n  <li><strong>Suivi<\/strong>: surveiller les journaux, l'\u00e9tat et la RAM, puis proc\u00e9der \u00e0 des ajustements progressifs.<\/li>\n<\/ul>\n\n<h2>Pourquoi la gestion des processus est importante<\/h2>\n\n<p>Je participe <strong>PHP-FPM<\/strong> l'ex\u00e9cution de chaque script PHP comme un processus distinct, et chaque requ\u00eate parall\u00e8le n\u00e9cessite son propre worker. Sans limites appropri\u00e9es, les requ\u00eates se bloquent dans les files d'attente, ce qui entra\u00eene <strong>Timeouts<\/strong> et des erreurs. Si je fixe des limites trop \u00e9lev\u00e9es, le pool de processus consomme toute la m\u00e9moire vive et le noyau commence \u00e0 <strong>\u00e9changer<\/strong>. Cet \u00e9quilibre n'est pas une question de hasard : je m'appuie sur des valeurs r\u00e9elles et je garde une marge de s\u00e9curit\u00e9. Ainsi, la latence reste faible et le d\u00e9bit stable, m\u00eame lorsque la charge varie.<\/p>\n\n<p>Ce qui m'importe, c'est une communication claire. <strong>valeur cible<\/strong>: Combien d'ex\u00e9cutions PHP simultan\u00e9es est-ce que je veux permettre sans \u00e9puiser la RAM ? En m\u00eame temps, je v\u00e9rifie si les goulots d'\u00e9tranglement se produisent plut\u00f4t dans la <strong>Base de donn\u00e9es<\/strong>, dans les API externes ou dans le serveur web. Ce n'est qu'une fois que j'ai identifi\u00e9 le goulot d'\u00e9tranglement que je choisis les valeurs appropri\u00e9es pour pm, pm.max_children et autres. Je commence de mani\u00e8re conservatrice, puis je mesure et augmente progressivement. Cela me permet d'\u00e9viter les red\u00e9marrages brutaux et les pannes inattendues.<\/p>\n\n\n<figure class=\"wp-block-image size-full is-resized\">\n  <img fetchpriority=\"high\" decoding=\"async\" src=\"https:\/\/webhosting.de\/wp-content\/uploads\/2025\/12\/php-fpm-serveradmin-4912.png\" alt=\"\" width=\"1536\" height=\"1024\"\/>\n<\/figure>\n\n\n<h2>Les trois modes pm : static, dynamic, ondemand<\/h2>\n\n<p>Le mode <strong>static<\/strong> tient toujours exactement pm.max_children processus pr\u00eats. Cela fournit des latences tr\u00e8s pr\u00e9visibles, car aucun processus de d\u00e9marrage n'est n\u00e9cessaire. J'utilise static lorsque la charge est tr\u00e8s r\u00e9guli\u00e8re et que suffisamment de RAM est disponible. Cependant, lorsque la demande varie, je gaspille facilement dans static. <strong>M\u00e9moire<\/strong>. C'est pourquoi j'utilise static de mani\u00e8re cibl\u00e9e l\u00e0 o\u00f9 j'ai besoin d'une ex\u00e9cution constante.<\/p>\n\n<p>Avec <strong>dynamique<\/strong> Je lance une quantit\u00e9 initiale et laisse la taille du pool osciller entre min_spare et max_spare. Ce mode convient au trafic par vagues, car les workers sont cr\u00e9\u00e9s et supprim\u00e9s selon les besoins. Je garde toujours suffisamment de processus inactifs pour absorber les pics sans temps d'attente. Cependant, un trop grand nombre de workers inactifs mobilise inutilement des ressources. <strong>RAM<\/strong>, c'est pourquoi je g\u00e8re la marge de s\u00e9curit\u00e9 de mani\u00e8re stricte. Ainsi, la piscine reste mobile sans gonfler.<\/p>\n\n<p>En mode <strong>ondemand<\/strong> Au d\u00e9part, il n'y a pas de workers, PHP-FPM ne les d\u00e9marre qu'en cas de requ\u00eates. Cela permet d'\u00e9conomiser de la m\u00e9moire pendant les phases de repos, mais le premier acc\u00e8s entra\u00eene une l\u00e9g\u00e8re latence. Je choisis ondemand pour les pools rarement appel\u00e9s, les outils d'administration ou les points de terminaison cron. Pour les sites web tr\u00e8s fr\u00e9quent\u00e9s, ondemand offre g\u00e9n\u00e9ralement des temps de r\u00e9ponse moins bons. Dans ce cas, je pr\u00e9f\u00e8re clairement dynamic avec des valeurs de r\u00e9serve correctement d\u00e9finies.<\/p>\n\n\n<figure class=\"wp-block-image size-full is-resized\">\n  <img decoding=\"async\" src=\"https:\/\/webhosting.de\/wp-content\/uploads\/2025\/12\/phpfpm_konfiguration_9542.png\" alt=\"\" width=\"1536\" height=\"1024\"\/>\n<\/figure>\n\n\n<h2>Dimensionner correctement pm.max_children<\/h2>\n\n<p>Je calcule <strong>pm.max_children<\/strong> \u00e0 partir de la RAM disponible pour PHP et de la m\u00e9moire moyenne par worker. Pour cela, je r\u00e9serve d'abord de la m\u00e9moire pour le syst\u00e8me, le serveur web, la base de donn\u00e9es et les caches afin que le syst\u00e8me ne tombe pas en panne. <strong>Externalisation<\/strong> fonctionne. Je divise la RAM restante par la consommation r\u00e9elle mesur\u00e9e du processus. \u00c0 partir de la th\u00e9orie, je retire une marge de s\u00e9curit\u00e9 de 20 \u00e0 30 % afin de compenser les valeurs aberrantes et les pics de charge. J'utilise le r\u00e9sultat comme valeur de d\u00e9part, puis j'observe l'effet.<\/p>\n\n<p>Je d\u00e9termine la consommation moyenne du processus \u00e0 l'aide d'outils tels que <strong>ps<\/strong>, top ou htop et je regarde RSS\/RES. Important : je mesure sous une charge typique, pas au ralenti. Si je charge beaucoup de plugins, de frameworks ou de grandes biblioth\u00e8ques, la consommation par worker grimpe sensiblement. De plus, le CPU limite la courbe : plus de processus n'aident pas si un <strong>Fil de discussion unique<\/strong>-Puissance du CPU limit\u00e9e par requ\u00eate. Si vous souhaitez approfondir vos connaissances sur les caract\u00e9ristiques du CPU, vous trouverez des informations g\u00e9n\u00e9rales sur <a href=\"https:\/\/webhosting.de\/fr\/php-single-thread-performance-wordpress-hosting-velocity\/\">Performances mono-thread<\/a>.<\/p>\n\n<p>Je garde mes hypoth\u00e8ses transparentes : quelle quantit\u00e9 de RAM est r\u00e9ellement disponible pour PHP ? Quelle est la taille d'un worker pour des requ\u00eates typiques ? Quels sont les pics qui se produisent ? Si les r\u00e9ponses sont correctes, je d\u00e9finis pm.max_children, je proc\u00e8de \u00e0 un rechargement en douceur et je v\u00e9rifie la RAM, les temps de r\u00e9ponse et les taux d'erreur. Ce n'est qu'ensuite que je continue \u00e0 augmenter ou \u00e0 diminuer petit \u00e0 petit.<\/p>\n\n<h2>Valeurs indicatives en fonction de la taille du serveur<\/h2>\n\n<p>Le tableau suivant me donne <strong>valeurs initiales<\/strong> Elle ne remplace pas les mesures, mais fournit des indications fiables pour les premiers r\u00e9glages. J'adapte les valeurs \u00e0 chaque application et les v\u00e9rifie \u00e0 l'aide d'un syst\u00e8me de surveillance. Si des r\u00e9serves restent inutilis\u00e9es, j'augmente prudemment les valeurs. Si le serveur atteint la limite de la m\u00e9moire vive, je r\u00e9duis les valeurs.<\/p>\n\n<table>\n  <thead>\n    <tr>\n      <th><strong>M\u00e9moire vive du serveur<\/strong><\/th>\n      <th><strong>RAM pour PHP<\/strong><\/th>\n      <th><strong>\u00d8 Mo\/travailleur<\/strong><\/th>\n      <th><strong>pm.max_children<\/strong> (D\u00e9but)<\/th>\n      <th><strong>Utilisation<\/strong><\/th>\n    <\/tr>\n  <\/thead>\n  <tbody>\n    <tr>\n      <td>1 \u00e0 2 Go<\/td>\n      <td>~1 Go<\/td>\n      <td>50-60<\/td>\n      <td>15\u201320<\/td>\n      <td>Petits sites, blogs<\/td>\n    <\/tr>\n    <tr>\n      <td>4 \u00e0 8 Go<\/td>\n      <td>~4 \u00e0 6 Go<\/td>\n      <td>60-80<\/td>\n      <td>30\u201380<\/td>\n      <td>Commerce, petites boutiques<\/td>\n    <\/tr>\n    <tr>\n      <td>16+ Go<\/td>\n      <td>~10\u201312 Go<\/td>\n      <td>70-90<\/td>\n      <td>100\u2013160<\/td>\n      <td>Charge \u00e9lev\u00e9e, API, boutiques<\/td>\n    <\/tr>\n  <\/tbody>\n<\/table>\n\n<p>Je lis le tableau de droite \u00e0 gauche : Est-ce que le <strong>Utilisation<\/strong> Pour le projet, je v\u00e9rifie si la RAM est r\u00e9serv\u00e9e de mani\u00e8re r\u00e9aliste pour PHP. Ensuite, je choisis une taille de worker adapt\u00e9e \u00e0 la base de code et aux extensions. Puis, je d\u00e9finis pm.max_children et observe l'effet en fonctionnement r\u00e9el. Le taux de r\u00e9ussite et la stabilit\u00e9 augmentent lorsque je documente clairement ces \u00e9tapes.<\/p>\n\n\n<figure class=\"wp-block-image size-full is-resized\">\n  <img decoding=\"async\" src=\"https:\/\/webhosting.de\/wp-content\/uploads\/2025\/12\/php-fpm-prozessmanagement-5124.png\" alt=\"\" width=\"1536\" height=\"1024\"\/>\n<\/figure>\n\n\n<h2>D\u00e9finir les valeurs de d\u00e9marrage, de r\u00e9serve et de demande<\/h2>\n\n<p>Avec <strong>pm.start_servers<\/strong> Je d\u00e9termine le nombre de processus imm\u00e9diatement disponibles. Une valeur trop faible g\u00e9n\u00e8re des d\u00e9marrages \u00e0 froid sous charge, une valeur trop \u00e9lev\u00e9e occupe inutilement de la m\u00e9moire vive. Je me base souvent sur 15 \u00e0 30 % de pm.max_children et j'arrondis lorsque la charge d\u00e9marre plut\u00f4t calmement. En cas de pics de trafic, je choisis une quantit\u00e9 de d\u00e9marrage l\u00e9g\u00e8rement plus \u00e9lev\u00e9e afin que les requ\u00eates ne s'accumulent pas avant qu'un nombre suffisant de workers ne soit disponible. Ce r\u00e9glage fin r\u00e9duit consid\u00e9rablement le temps de r\u00e9ponse initial.<\/p>\n\n<p>Les valeurs <strong>pm.min_spare_servers<\/strong> et pm.max_spare_servers d\u00e9finissent la plage d'inactivit\u00e9. Je garde suffisamment de travailleurs libres pour que les nouvelles demandes puissent \u00eatre trait\u00e9es imm\u00e9diatement, mais pas trop pour \u00e9viter que les processus inactifs ne gaspillent de la m\u00e9moire. Pour les boutiques, je pr\u00e9f\u00e8re d\u00e9finir une plage plus \u00e9troite afin de lisser les pics. Avec <strong>pm.max_requests<\/strong> Je recycle les processus apr\u00e8s quelques centaines de requ\u00eates afin de limiter la d\u00e9rive de m\u00e9moire. Pour les applications discr\u00e8tes, je choisis 500 \u00e0 800, en cas de suspicion de fuites, je choisis d\u00e9lib\u00e9r\u00e9ment une valeur inf\u00e9rieure.<\/p>\n\n<h2>Monitoring et recherche d'erreurs<\/h2>\n\n<p>Je v\u00e9rifie r\u00e9guli\u00e8rement <strong>Logs<\/strong>, pages d'\u00e9tat et RAM. Les avertissements concernant les limites pm.max_children atteintes sont pour moi un signal clair qu'il faut augmenter la limite sup\u00e9rieure ou optimiser le code\/la base de donn\u00e9es. Si les erreurs 502\/504 s'accumulent, je consulte les journaux du serveur web et les files d'attente. Des fluctuations importantes de la latence indiquent un nombre insuffisant de processus, des E\/S bloquantes ou des co\u00fbts de processus trop \u00e9lev\u00e9s. Je commence par examiner les faits concrets, puis je r\u00e9agis par petites \u00e9tapes, jamais par des sauts XXL.<\/p>\n\n<p>Je d\u00e9tecte plus rapidement les goulots d'\u00e9tranglement lorsque je <strong>Temps d'attente<\/strong> Je mesure tout au long de la cha\u00eene : serveur web, PHP-FPM, base de donn\u00e9es, services externes. Si le temps de traitement backend augmente uniquement pour certaines routes, j'isole les causes \u00e0 l'aide du profilage. Si les temps d'attente se produisent partout, je commence par la taille du serveur et du pool. Il est \u00e9galement utile d'examiner les files d'attente des travailleurs et les processus en statut D. Ce n'est qu'une fois que j'ai compris la situation que je modifie les limites \u2013 et je documente soigneusement chaque modification.<\/p>\n\n\n<figure class=\"wp-block-image size-full is-resized\">\n  <img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/webhosting.de\/wp-content\/uploads\/2025\/12\/phpfpm_nachtarbeit_tech5982.png\" alt=\"\" width=\"1536\" height=\"1024\"\/>\n<\/figure>\n\n\n<h2>Interaction entre le serveur web et PHP-FPM<\/h2>\n\n<p>Je veille \u00e0 ce que <strong>Serveur web<\/strong>Les limites et PHP-FPM fonctionnent en harmonie. Un nombre trop \u00e9lev\u00e9 de connexions simultan\u00e9es au serveur web avec trop peu de workers entra\u00eene des files d'attente et des d\u00e9lais d'attente. Si le nombre de workers est \u00e9lev\u00e9, mais que le serveur web limite l'acceptation, les performances restent faibles. Des param\u00e8tres tels que worker_connections, event-Loop et Keep-Alive ont un effet direct sur la charge PHP. Des conseils pratiques pour un r\u00e9glage pr\u00e9cis sont fournis dans la section <a href=\"https:\/\/webhosting.de\/fr\/threadpool-serveur-web-apache-nginx-litespeed-optimisation-configuration\/\">Pools de threads dans le serveur web<\/a>.<\/p>\n\n<p>Je garde <strong>Keep-Alive<\/strong>-fen\u00eatre temporelle afin que les connexions inactives ne bloquent pas inutilement les travailleurs. Pour les ressources statiques, je privil\u00e9gie une mise en cache agressive avant PHP afin d'\u00e9viter de surcharger le pool. Les caches proxy invers\u00e9s sont \u00e9galement utiles lorsque des r\u00e9ponses identiques sont fr\u00e9quemment consult\u00e9es. Cela me permet de maintenir pm.max_children \u00e0 un niveau bas tout en acc\u00e9l\u00e9rant la livraison. R\u00e9duire la charge de travail par requ\u00eate est souvent la solution la plus efficace.<\/p>\n\n<h2>R\u00e9glages fins dans php-fpm.conf<\/h2>\n\n<p>Je vais au-del\u00e0 des valeurs fondamentales et j'ajuste les <strong>Param\u00e8tres de la piscine<\/strong> bien. Avec <strong>pm.max_spawn_rate<\/strong> je limite la vitesse \u00e0 laquelle de nouveaux workers peuvent \u00eatre cr\u00e9\u00e9s afin que le serveur ne lance pas de processus de mani\u00e8re trop agressive lors des pics de charge et ne tombe pas dans le CPU thrashing. Pour ondemand, je d\u00e9finis avec <strong>pm.process_idle_timeout<\/strong> d\u00e9termin\u00e9 \u00e0 quelle vitesse les workers inutilis\u00e9s disparaissent \u2013 trop court, cela g\u00e9n\u00e8re des frais g\u00e9n\u00e9raux de d\u00e9marrage, trop long, cela mobilise de la RAM. Dans le cas du <strong>\u00e9couter<\/strong>-Socket, je choisis entre Unix-Socket et TCP. Un Unix-Socket r\u00e9duit la charge et offre une attribution claire des droits via <em>listen.owner<\/em>, <em>listen.group<\/em> et <em>listen.mode<\/em>. Pour les deux variantes, je mets <strong>listen.backlog<\/strong> suffisamment \u00e9lev\u00e9 pour que les rafales entrantes aboutissent dans la m\u00e9moire tampon du noyau au lieu d'\u00eatre imm\u00e9diatement rejet\u00e9es. Avec <strong>rlimit_files<\/strong> j'augmente si n\u00e9cessaire le nombre de fichiers ouverts par travailleur, ce qui apporte de la stabilit\u00e9 en cas de nombreux t\u00e9l\u00e9chargements et chargements simultan\u00e9s. Et si des priorit\u00e9s sont n\u00e9cessaires, j'utilise <strong>priorit\u00e9 du processus<\/strong>, afin de traiter les pools peu critiques de mani\u00e8re quelque peu subordonn\u00e9e du point de vue du CPU.<\/p>\n\n<h2>Slowlog et protection contre les blocages<\/h2>\n\n<p>Pour rendre visibles les requ\u00eates lentes, j'active le <strong>Slowlog<\/strong>. Avec <strong>request_slowlog_timeout<\/strong> Je d\u00e9finis le seuil (par exemple 2 \u00e0 3 secondes) \u00e0 partir duquel une trace de pile est enregistr\u00e9e dans le <strong>slowlog<\/strong> est \u00e9crit. Je trouve ainsi des E\/S bloquantes, des boucles co\u00fbteuses ou des verrous inattendus. Contre les v\u00e9ritables blocages, j'utilise <strong>request_terminate_timeout<\/strong>, qui interrompt brutalement lorsqu'une requ\u00eate dure trop longtemps. Je consid\u00e8re que ces d\u00e9lais sont coh\u00e9rents avec <em>max_execution_time<\/em> \u00e0 partir du PHP et des d\u00e9lais d'expiration du serveur Web, afin qu'aucune couche ne se d\u00e9tache avant les autres. Dans la pratique, je commence de mani\u00e8re conservatrice, j'analyse les slowlogs sous charge et j'ajuste progressivement les seuils jusqu'\u00e0 ce que les signaux soient significatifs, sans saturer le journal.<\/p>\n\n<h2>Opcache, memory_limit et leur influence sur la taille des workers<\/h2>\n\n<p>Je me r\u00e9f\u00e8re au <strong>Opcache<\/strong> dans ma planification RAM. Sa zone de m\u00e9moire partag\u00e9e ne compte pas par travailleur, mais est utilis\u00e9e conjointement par tous les processus. Taille et fragmentation (<em>opcache.memory_consumption<\/em>, <em>interned_strings_buffer<\/em>) influencent consid\u00e9rablement le temps de pr\u00e9chauffage et le taux de r\u00e9ussite. Un Opcache bien dimensionn\u00e9 r\u00e9duit la pression sur le CPU et la RAM par requ\u00eate, car moins de code est recompil\u00e9. Dans le m\u00eame temps, je remarque que <strong>memory_limit<\/strong>: une valeur \u00e9lev\u00e9e prot\u00e8ge certes contre les cas isol\u00e9s de m\u00e9moire insuffisante, mais augmente le budget th\u00e9orique dans le pire des cas par travailleur. Je planifie donc avec une moyenne mesur\u00e9e plus une marge, et non avec la simple valeur memory_limit. Des fonctionnalit\u00e9s telles que le pr\u00e9chargement ou le JIT augmentent les besoins en m\u00e9moire \u2013 je les teste de mani\u00e8re cibl\u00e9e et calcule la consommation suppl\u00e9mentaire dans le calcul pm.max_children.<\/p>\n\n<h2>S\u00e9parer et hi\u00e9rarchiser les pools<\/h2>\n\n<p>Je partage les applications sur <strong>plusieurs pools<\/strong> lorsque les profils de charge diff\u00e8rent consid\u00e9rablement. Un pool pour le trafic frontal, un pour l'administration\/le backend, un troisi\u00e8me pour Cron\/les t\u00e9l\u00e9chargements : c'est ainsi que j'isole les pics et que j'attribue des limites diff\u00e9renci\u00e9es. Pour les points d'extr\u00e9mit\u00e9 rarement fr\u00e9quent\u00e9s, je d\u00e9finis <em>ondemand<\/em> avec un d\u00e9lai d'inactivit\u00e9 court pour le frontend <em>dynamique<\/em> avec une marge de man\u0153uvre r\u00e9duite. \u00c0 propos de <strong>utilisateur\/groupe<\/strong> et, le cas \u00e9ch\u00e9ant,. <em>chroot<\/em> je veille \u00e0 une isolation propre, tandis que les droits Socket r\u00e9gissent quel processus du serveur web peut acc\u00e9der. Lorsque des priorit\u00e9s sont requises, le frontend re\u00e7oit plus <em>pm.max_children<\/em> et, le cas \u00e9ch\u00e9ant, une <em>priorit\u00e9 du processus<\/em>, tandis que Cron\/Reports fonctionne avec un budget plus modeste et une priorit\u00e9 moindre. Ainsi, l'interface utilisateur reste r\u00e9active, m\u00eame lorsque des t\u00e2ches lourdes sont ex\u00e9cut\u00e9es en arri\u00e8re-plan.<\/p>\n\n<h2>Utiliser correctement les points finaux d'\u00e9tat<\/h2>\n\n<p>Pour le diagnostic de dur\u00e9e de fonctionnement, j'active <strong>pm.status_path<\/strong> et en option <strong>ping.path<\/strong> par pool. Dans le statut, je vois les travailleurs actifs\/inactifs qui <em>File d'attente des listes<\/em>, des compteurs li\u00e9s au d\u00e9bit et des m\u00e9triques de requ\u00eates lentes. Une file d'attente de listes en croissance constante ou un nombre de travailleurs inactifs toujours \u00e9gal \u00e0 0 sont pour moi des signaux d'alarme. Je prot\u00e8ge ces points finaux derri\u00e8re Auth et un r\u00e9seau interne afin qu'aucun d\u00e9tail op\u00e9rationnel ne soit divulgu\u00e9 \u00e0 l'ext\u00e9rieur. De plus, j'active <strong>catch_workers_output<\/strong>, lorsque je souhaite collecter rapidement les donn\u00e9es stdout\/stderr des workers, par exemple en cas d'erreurs difficiles \u00e0 reproduire. Je combine ces signaux avec des m\u00e9triques syst\u00e8me (RAM, CPU, E\/S) afin de d\u00e9cider si je dois augmenter pm.max_children, ajuster les valeurs de r\u00e9serve ou intervenir sur l'application.<\/p>\n\n<h2>Particularit\u00e9s dans les conteneurs et les VM<\/h2>\n\n<p>\u00c0 l'adresse suivante : <strong>glanage<\/strong> et les petites VM, je tiens compte des limites cgroup et du risque li\u00e9 au OOM killer. Je d\u00e9finis pm.max_children strictement selon le <em>Limite de m\u00e9moire du conteneur<\/em> et teste les pics de charge afin qu'aucun worker ne soit interrompu. Sans swap dans les conteneurs, la marge de s\u00e9curit\u00e9 est particuli\u00e8rement importante. Pour les quotas CPU, j'adapte le nombre de workers au nombre de vCPU disponibles : si l'application est li\u00e9e au CPU, un parall\u00e9lisme accru entra\u00eene plut\u00f4t des files d'attente qu'un d\u00e9bit. Les charges de travail li\u00e9es \u00e0 l'E\/S supportent davantage de processus tant que le budget RAM le permet. De plus, je d\u00e9finis <strong>seuil_red\u00e9marrage_d'urgence<\/strong> et <strong>intervalle_de_red\u00e9marrage_d'urgence<\/strong> pour le processus ma\u00eetre, afin d'intercepter une spirale de plantage si un bug rare affecte plusieurs enfants en peu de temps. Ainsi, le service reste disponible pendant que j'analyse la cause.<\/p>\n\n<h2>D\u00e9ploiements et rechargements fluides sans interruption de service<\/h2>\n\n<p>Je pr\u00e9vois <strong>Recharges<\/strong> de mani\u00e8re \u00e0 ce que les requ\u00eates en cours soient men\u00e9es \u00e0 bien. Un <em>rechargement gracieux<\/em> (par exemple via systemd reload) applique les nouvelles configurations sans interrompre brutalement les connexions ouvertes. Je maintiens le chemin d'acc\u00e8s au socket stable afin que le serveur web ne d\u00e9tecte aucune interruption de connexion. Lors des changements de version qui invalident une grande partie de l'Opcache, je pr\u00e9chauffe le cache (pr\u00e9chargement\/requ\u00eates de pr\u00e9chauffage) afin de limiter les pics de latence imm\u00e9diatement apr\u00e8s le d\u00e9ploiement. Je teste d'abord les modifications importantes sur un pool plus petit ou dans une instance Canary avec une configuration identique avant de d\u00e9ployer les valeurs \u00e0 grande \u00e9chelle. Chaque modification est enregistr\u00e9e dans mon journal des modifications avec un horodatage et des captures d'\u00e9cran des m\u00e9triques, ce qui r\u00e9duit le temps de d\u00e9pannage en cas d'effets secondaires inattendus.<\/p>\n\n<h2>Comportement en rafale et files d'attente<\/h2>\n\n<p>Je compense les pics de charge avec un <strong>Conception des files d'attente<\/strong> Je mets <strong>listen.backlog<\/strong> suffisamment \u00e9lev\u00e9 pour que le noyau puisse temporairement mettre en m\u00e9moire tampon davantage de tentatives de connexion. Du c\u00f4t\u00e9 du serveur web, je limite le nombre maximal de connexions FastCGI simultan\u00e9es par pool de mani\u00e8re \u00e0 ce qu'il soit <em>pm.max_children<\/em> convient. Ainsi, les rafales s'accumulent plut\u00f4t bri\u00e8vement dans le serveur web (peu co\u00fbteux) que profond\u00e9ment dans PHP (co\u00fbteux). Je mesure la <em>File d'attente des listes<\/em> dans l'\u00e9tat FPM : s'il augmente r\u00e9guli\u00e8rement, j'augmente soit le nombre de travailleurs, j'optimise les taux de r\u00e9ussite du cache ou je r\u00e9duis les valeurs Keep-Alive agressives. L'objectif est, en cas de pics, de <em>Time-to-First-Byte<\/em> stable, au lieu de laisser les requ\u00eates s'enlisent dans des files d'attente interminables.<\/p>\n\n<h2>Flux de travail pratique pour les ajustements<\/h2>\n\n<p>Je commence par un <strong>Audit<\/strong>: budget RAM, taille du processus, profils E\/S. Ensuite, je d\u00e9finis des valeurs de d\u00e9part conservatrices pour pm.max_children et le mode pm. Je proc\u00e8de ensuite \u00e0 des tests de charge ou observe les pics d'activit\u00e9 r\u00e9els. J'enregistre toutes les modifications, y compris les m\u00e9triques et les plages horaires. Apr\u00e8s chaque ajustement, je v\u00e9rifie la RAM, la latence P50\/P95 et les taux d'erreur. Ce n'est qu'ensuite que je passe \u00e0 l'\u00e9tape suivante.<\/p>\n\n<p>Lorsque je me retrouve \u00e0 plusieurs reprises \u00e0 la limite, je ne r\u00e9agis pas imm\u00e9diatement de mani\u00e8re excessive. <strong>Travailleur<\/strong>-Nombre. Je commence par optimiser les requ\u00eates, les taux de r\u00e9ussite du cache et les fonctions co\u00fbteuses. Je d\u00e9place les t\u00e2ches gourmandes en E\/S vers des files d'attente et raccourcis les temps de r\u00e9ponse. Ce n'est que lorsque l'application fonctionne efficacement que j'augmente la taille du pool. Ce processus permet d'\u00e9conomiser des ressources et d'\u00e9viter des dommages cons\u00e9cutifs ailleurs.<\/p>\n\n\n<figure class=\"wp-block-image size-full is-resized\">\n  <img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/webhosting.de\/wp-content\/uploads\/2025\/12\/phpfpm_schreibtisch_7321.png\" alt=\"\" width=\"1536\" height=\"1024\"\/>\n<\/figure>\n\n\n<h2>Sc\u00e9narios types : exemples de valeurs<\/h2>\n\n<p>Sur un serveur virtuel de 2 Go, je r\u00e9serve environ <strong>1 GB<\/strong> pour PHP-FPM et je d\u00e9finis une consommation de worker d'environ 50 \u00e0 60 Mo. Je commence donc avec pm.max_children \u00e0 15-20 et j'utilise dynamic avec une petite quantit\u00e9 de d\u00e9part. Je maintiens min_spare \u00e0 2-3 et max_spare \u00e0 5-6. Je d\u00e9finis pm.max_requests \u00e0 500 afin que les processus soient r\u00e9guli\u00e8rement remplac\u00e9s. Ces param\u00e8tres garantissent des temps de r\u00e9ponse stables pour les petits projets.<\/p>\n\n<p>Avec 8 Go de RAM, je pr\u00e9vois g\u00e9n\u00e9ralement 4 \u00e0 6 Go pour <strong>PHP<\/strong> et je d\u00e9finis des tailles de worker comprises entre 60 et 80 Mo. Il en r\u00e9sulte 30 \u00e0 80 processus enfants comme plage de d\u00e9marrage. pm.start_servers est compris entre 15 et 20, min_spare entre 10 et 15, max_spare entre 25 et 30. Je choisis pm.max_requests entre 500 et 800. Sous charge, je v\u00e9rifie si le pic de RAM laisse de la marge, puis j'augmente prudemment.<\/p>\n\n<p>Dans les configurations \u00e0 forte charge avec plus de 16 Go de RAM, je r\u00e9serve 10 \u00e0 12 Go pour <strong>FPM<\/strong>. Avec 70 \u00e0 90 Mo par travailleur, j'arrive rapidement \u00e0 100 \u00e0 160 processus. Le choix entre statique et dynamique d\u00e9pend de la forme de la charge. Le mode statique est convaincant pour une charge \u00e9lev\u00e9e permanente, le mode dynamique pour une demande fluctuante. Dans les deux cas, une surveillance constante reste obligatoire.<\/p>\n\n<h2>\u00c9viter les obstacles et fixer des priorit\u00e9s<\/h2>\n\n<p>Je ne confonds pas le nombre de <strong>Visiteurs<\/strong> avec le nombre de scripts PHP simultan\u00e9s. De nombreuses consultations de pages atteignent les caches, fournissent des fichiers statiques ou bloquent en dehors de PHP. C'est pourquoi je dimensionne pm.max_children en fonction du temps PHP mesur\u00e9, et non en fonction des sessions. Si les processus sont d\u00e9finis de mani\u00e8re trop \u00e9conome, je constate des requ\u00eates en attente et des taux d'erreur croissants. Si les valeurs sont trop \u00e9lev\u00e9es, la m\u00e9moire bascule dans le swap et tout ralentit.<\/p>\n\n<p>Une erreur fr\u00e9quente : plus de processus signifie plus de <strong>Vitesse<\/strong>. En r\u00e9alit\u00e9, c'est l'\u00e9quilibre entre le CPU, l'E\/S et la RAM qui compte. Si le CPU atteint 100 % et que la latence augmente rapidement, l'ajout de travailleurs suppl\u00e9mentaires n'aide gu\u00e8re. Il vaut mieux \u00e9liminer le v\u00e9ritable goulot d'\u00e9tranglement ou r\u00e9duire la charge via le cache. Le guide explique pourquoi les travailleurs sont souvent le goulot d'\u00e9tranglement. <a href=\"https:\/\/webhosting.de\/fr\/php-workers-hosting-goulot-detranglement-guide-balance\/\">PHP Worker comme goulot d'\u00e9tranglement<\/a>.<\/p>\n\n\n<figure class=\"wp-block-image size-full is-resized\">\n  <img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/webhosting.de\/wp-content\/uploads\/2025\/12\/phpfpm-serverkonfig-7342.png\" alt=\"\" width=\"1536\" height=\"1024\"\/>\n<\/figure>\n\n\n<h2>En bref<\/h2>\n\n<p>Je d\u00e9termine d'abord le r\u00e9el <strong>RAM<\/strong>-Consommation par travailleur et je d\u00e9finis pm.max_children avec une marge. Ensuite, je s\u00e9lectionne le mode pm adapt\u00e9 \u00e0 la forme de charge et j'\u00e9quilibre les valeurs de d\u00e9marrage et de r\u00e9serve. Avec pm.max_requests, je maintiens les processus \u00e0 jour sans surcharge inutile. Je transf\u00e8re les journaux, les statuts et les m\u00e9triques vers un syst\u00e8me de surveillance propre afin que chaque modification reste mesurable. Je parviens ainsi \u00e0 obtenir des temps de r\u00e9ponse courts, des pools stables et une charge serveur qui dispose de r\u00e9serves pour les pics.<\/p>","protected":false},"excerpt":{"rendered":"<p>Guide complet pour l'optimisation de php-fpm : apprenez \u00e0 r\u00e9gler de mani\u00e8re optimale pm.max_children et d'autres param\u00e8tres de processus afin de maximiser les performances de votre h\u00e9bergement php.<\/p>","protected":false},"author":1,"featured_media":16046,"comment_status":"","ping_status":"","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"_crdt_document":"","inline_featured_image":false,"footnotes":""},"categories":[780],"tags":[],"class_list":["post-16053","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-administration-anleitungen"],"acf":[],"_wp_attached_file":null,"_wp_attachment_metadata":null,"litespeed-optimize-size":null,"litespeed-optimize-set":null,"_elementor_source_image_hash":null,"_wp_attachment_image_alt":null,"stockpack_author_name":null,"stockpack_author_url":null,"stockpack_provider":null,"stockpack_image_url":null,"stockpack_license":null,"stockpack_license_url":null,"stockpack_modification":null,"color":null,"original_id":null,"original_url":null,"original_link":null,"unsplash_location":null,"unsplash_sponsor":null,"unsplash_exif":null,"unsplash_attachment_metadata":null,"_elementor_is_screenshot":null,"surfer_file_name":null,"surfer_file_original_url":null,"envato_tk_source_kit":null,"envato_tk_source_index":null,"envato_tk_manifest":null,"envato_tk_folder_name":null,"envato_tk_builder":null,"envato_elements_download_event":null,"_menu_item_type":null,"_menu_item_menu_item_parent":null,"_menu_item_object_id":null,"_menu_item_object":null,"_menu_item_target":null,"_menu_item_classes":null,"_menu_item_xfn":null,"_menu_item_url":null,"_trp_menu_languages":null,"rank_math_primary_category":null,"rank_math_title":null,"inline_featured_image":null,"_yoast_wpseo_primary_category":null,"rank_math_schema_blogposting":null,"rank_math_schema_videoobject":null,"_oembed_049c719bc4a9f89deaead66a7da9fddc":null,"_oembed_time_049c719bc4a9f89deaead66a7da9fddc":null,"_yoast_wpseo_focuskw":null,"_yoast_wpseo_linkdex":null,"_oembed_27e3473bf8bec795fbeb3a9d38489348":null,"_oembed_c3b0f6959478faf92a1f343d8f96b19e":null,"_trp_translated_slug_en_us":null,"_wp_desired_post_slug":null,"_yoast_wpseo_title":null,"tldname":null,"tldpreis":null,"tldrubrik":null,"tldpolicylink":null,"tldsize":null,"tldregistrierungsdauer":null,"tldtransfer":null,"tldwhoisprivacy":null,"tldregistrarchange":null,"tldregistrantchange":null,"tldwhoisupdate":null,"tldnameserverupdate":null,"tlddeletesofort":null,"tlddeleteexpire":null,"tldumlaute":null,"tldrestore":null,"tldsubcategory":null,"tldbildname":null,"tldbildurl":null,"tldclean":null,"tldcategory":null,"tldpolicy":null,"tldbesonderheiten":null,"tld_bedeutung":null,"_oembed_d167040d816d8f94c072940c8009f5f8":null,"_oembed_b0a0fa59ef14f8870da2c63f2027d064":null,"_oembed_4792fa4dfb2a8f09ab950a73b7f313ba":null,"_oembed_33ceb1fe54a8ab775d9410abf699878d":null,"_oembed_fd7014d14d919b45ec004937c0db9335":null,"_oembed_21a029d076783ec3e8042698c351bd7e":null,"_oembed_be5ea8a0c7b18e658f08cc571a909452":null,"_oembed_a9ca7a298b19f9b48ec5914e010294d2":null,"_oembed_f8db6b27d08a2bb1f920e7647808899a":null,"_oembed_168ebde5096e77d8a89326519af9e022":null,"_oembed_cdb76f1b345b42743edfe25481b6f98f":null,"_oembed_87b0613611ae54e86e8864265404b0a1":null,"_oembed_27aa0e5cf3f1bb4bc416a4641a5ac273":null,"_oembed_time_27aa0e5cf3f1bb4bc416a4641a5ac273":null,"_tldname":null,"_tldclean":null,"_tldpreis":null,"_tldcategory":null,"_tldsubcategory":null,"_tldpolicy":null,"_tldpolicylink":null,"_tldsize":null,"_tldregistrierungsdauer":null,"_tldtransfer":null,"_tldwhoisprivacy":null,"_tldregistrarchange":null,"_tldregistrantchange":null,"_tldwhoisupdate":null,"_tldnameserverupdate":null,"_tlddeletesofort":null,"_tlddeleteexpire":null,"_tldumlaute":null,"_tldrestore":null,"_tldbildname":null,"_tldbildurl":null,"_tld_bedeutung":null,"_tldbesonderheiten":null,"_oembed_ad96e4112edb9f8ffa35731d4098bc6b":null,"_oembed_8357e2b8a2575c74ed5978f262a10126":null,"_oembed_3d5fea5103dd0d22ec5d6a33eff7f863":null,"_eael_widget_elements":null,"_oembed_0d8a206f09633e3d62b95a15a4dd0487":null,"_oembed_time_0d8a206f09633e3d62b95a15a4dd0487":null,"_aioseo_description":null,"_eb_attr":null,"_eb_data_table":null,"_oembed_819a879e7da16dd629cfd15a97334c8a":null,"_oembed_time_819a879e7da16dd629cfd15a97334c8a":null,"_acf_changed":null,"_wpcode_auto_insert":null,"_edit_last":null,"_edit_lock":null,"_oembed_e7b913c6c84084ed9702cb4feb012ddd":null,"_oembed_bfde9e10f59a17b85fc8917fa7edf782":null,"_oembed_time_bfde9e10f59a17b85fc8917fa7edf782":null,"_oembed_03514b67990db061d7c4672de26dc514":null,"_oembed_time_03514b67990db061d7c4672de26dc514":null,"rank_math_news_sitemap_robots":null,"rank_math_robots":null,"_eael_post_view_count":"2664","_trp_automatically_translated_slug_ru_ru":null,"_trp_automatically_translated_slug_et":null,"_trp_automatically_translated_slug_lv":null,"_trp_automatically_translated_slug_fr_fr":null,"_trp_automatically_translated_slug_en_us":null,"_wp_old_slug":null,"_trp_automatically_translated_slug_da_dk":null,"_trp_automatically_translated_slug_pl_pl":null,"_trp_automatically_translated_slug_es_es":null,"_trp_automatically_translated_slug_hu_hu":null,"_trp_automatically_translated_slug_fi":null,"_trp_automatically_translated_slug_ja":null,"_trp_automatically_translated_slug_lt_lt":null,"_elementor_edit_mode":null,"_elementor_template_type":null,"_elementor_version":null,"_elementor_pro_version":null,"_wp_page_template":null,"_elementor_page_settings":null,"_elementor_data":null,"_elementor_css":null,"_elementor_conditions":null,"_happyaddons_elements_cache":null,"_oembed_75446120c39305f0da0ccd147f6de9cb":null,"_oembed_time_75446120c39305f0da0ccd147f6de9cb":null,"_oembed_3efb2c3e76a18143e7207993a2a6939a":null,"_oembed_time_3efb2c3e76a18143e7207993a2a6939a":null,"_oembed_59808117857ddf57e478a31d79f76e4d":null,"_oembed_time_59808117857ddf57e478a31d79f76e4d":null,"_oembed_965c5b49aa8d22ce37dfb3bde0268600":null,"_oembed_time_965c5b49aa8d22ce37dfb3bde0268600":null,"_oembed_81002f7ee3604f645db4ebcfd1912acf":null,"_oembed_time_81002f7ee3604f645db4ebcfd1912acf":null,"_elementor_screenshot":null,"_oembed_7ea3429961cf98fa85da9747683af827":null,"_oembed_time_7ea3429961cf98fa85da9747683af827":null,"_elementor_controls_usage":null,"_elementor_page_assets":[],"_elementor_screenshot_failed":null,"theplus_transient_widgets":null,"_eael_custom_js":null,"_wp_old_date":null,"_trp_automatically_translated_slug_it_it":null,"_trp_automatically_translated_slug_pt_pt":null,"_trp_automatically_translated_slug_zh_cn":null,"_trp_automatically_translated_slug_nl_nl":null,"_trp_automatically_translated_slug_pt_br":null,"_trp_automatically_translated_slug_sv_se":null,"rank_math_analytic_object_id":null,"rank_math_internal_links_processed":null,"_trp_automatically_translated_slug_ro_ro":null,"_trp_automatically_translated_slug_sk_sk":null,"_trp_automatically_translated_slug_bg_bg":null,"_trp_automatically_translated_slug_sl_si":null,"litespeed_vpi_list":null,"litespeed_vpi_list_mobile":null,"rank_math_seo_score":null,"rank_math_contentai_score":null,"ilj_limitincominglinks":null,"ilj_maxincominglinks":null,"ilj_limitoutgoinglinks":null,"ilj_maxoutgoinglinks":null,"ilj_limitlinksperparagraph":null,"ilj_linksperparagraph":null,"ilj_blacklistdefinition":null,"ilj_linkdefinition":null,"_eb_reusable_block_ids":null,"rank_math_focus_keyword":"php-fpm tuning","rank_math_og_content_image":null,"_yoast_wpseo_metadesc":null,"_yoast_wpseo_content_score":null,"_yoast_wpseo_focuskeywords":null,"_yoast_wpseo_keywordsynonyms":null,"_yoast_wpseo_estimated-reading-time-minutes":null,"rank_math_description":null,"surfer_last_post_update":null,"surfer_last_post_update_direction":null,"surfer_keywords":null,"surfer_location":null,"surfer_draft_id":null,"surfer_permalink_hash":null,"surfer_scrape_ready":null,"_thumbnail_id":"16046","footnotes":null,"_links":{"self":[{"href":"https:\/\/webhosting.de\/fr\/wp-json\/wp\/v2\/posts\/16053","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/webhosting.de\/fr\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/webhosting.de\/fr\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/webhosting.de\/fr\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/webhosting.de\/fr\/wp-json\/wp\/v2\/comments?post=16053"}],"version-history":[{"count":0,"href":"https:\/\/webhosting.de\/fr\/wp-json\/wp\/v2\/posts\/16053\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/webhosting.de\/fr\/wp-json\/wp\/v2\/media\/16046"}],"wp:attachment":[{"href":"https:\/\/webhosting.de\/fr\/wp-json\/wp\/v2\/media?parent=16053"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/webhosting.de\/fr\/wp-json\/wp\/v2\/categories?post=16053"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/webhosting.de\/fr\/wp-json\/wp\/v2\/tags?post=16053"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}