Voici un article technique détaillé sur le tuning de PHP-FPM (FastCGI Process Manager), un élément essentiel pour optimiser les performances PHP dans les environnements à charge variable (sites web, applications, API, etc.).
🎯 Objectifs
-
Comprendre le fonctionnement des pools PHP-FPM
-
Ajuster correctement les paramètres de gestion des processus (
pm.*) -
Optimiser l’utilisation CPU et RAM
-
Éviter la saturation ou le sous-emploi des ressources
-
Adapter PHP-FPM selon la charge réelle
📁 Localisation des fichiers de configuration
-
Ubuntu/Debian :
/etc/php/X.X/fpm/pool.d/www.conf
(ou un fichier par site/pool personnalisé)
🧠 Rappel : comment fonctionne PHP-FPM ?PHP-FPM gère des processus PHP.
-
Chaque requête PHP (via Apache, Nginx…) est traitée par un processus FPM.
-
Ces processus sont gérés par un pool dont les paramètres sont tuneables.
⚙️ Paramètres principaux de tuning (www.conf ou autres pools)
🛠️ 1. pm (Process Manager)
pm = dynamic
Types disponibles :
-
static: nombre fixe de processus (concurrent requis constant) -
dynamic: s’adapte à la charge (le plus courant) -
ondemand: ne crée de processus que sur requête
🧮 2. Paramètres liés à pm = dynamic
pm.max_children = 20
pm.start_servers = 5
pm.min_spare_servers = 3
pm.max_spare_servers = 10
-
pm.max_children: nombre maximal de processus PHP (important) -
start_servers: nombre de processus au démarrage -
min_spare_servers/max_spare_servers: fourchette des « processus dormants »
⚠️ Cas critique
Si pm.max_children est trop faible :
-
PHP refuse des connexions → Erreurs 502 / lenteurs
Si pm.max_children est trop élevé :
-
Surcharge mémoire → OOM (Out Of Memory)
🔁 Exemple de tuning pour un site avec charge moyenne (2 Go de RAM)
pm = dynamic
pm.max_children = 20
pm.start_servers = 5
pm.min_spare_servers = 2
pm.max_spare_servers = 10
🔁 Exemple de tuning pour un serveur mutualisé avec charge élevée (8 Go RAM)
pm = dynamic
pm.max_children = 80
pm.start_servers = 20
pm.min_spare_servers = 10
pm.max_spare_servers = 30
🌱 Exemple pour ondemand (faible trafic)
pm = ondemand
pm.max_children = 10
pm.process_idle_timeout = 10s
💡 Moins réactif, mais très léger pour de petits sites (admin, landing page…)
📏 Calculer pm.max_children
Étapes :
-
Lancer un site PHP réel
-
Observer la mémoire moyenne d’un process PHP-FPM :
ps -ylC php-fpm8.1 --sort:rss | awk '{ SUM += $8 } END { print SUM/NR/1024 " MB" }'
Exemple : chaque process prend 40 Mo
-
Si serveur = 2 Go RAM, on garde ~1 Go pour le reste :
Disponible pour FPM : 1024 Mo
Processus PHP : 40 Mo chacun
pm.max_children = 1024 / 40 = ~25
Surveillance de la charge PHP-FPM (Apache + Nginx)
Le module status de PHP-FPM vous permet de surveiller en temps réel les processus PHP, la file d’attente, le nombre de connexions, etc.
📍 Étape 1 — Activer pm.status_path dans le pool FPM concerné
Dans /etc/php/8.1/fpm/pool.d/www.conf ou tout autre pool :
pm.status_path = /status
Ensuite, redémarrez PHP-FPM :
sudo systemctl restart php8.1-fpm
🔗 Pour Nginx
Ajoutez cette section dans votre server {} (ex : /etc/nginx/sites-available/default) :
🔗 Pour Apache
Étape 1 : Activer les modules nécessaires
sudo a2enmod proxy_fcgi setenvif
sudo systemctl reload apache2
-
On protège
/statuset/pingvia l’adresse IP locale (127.0.0.1) -
On utilise la connexion par socket Unix au pool PHP-FPM
Recharger Apache :
sudo systemctl reload apache2
✅ Vérification
Depuis le serveur, testez avec :
curl http://127.0.0.1/status
Sortie typique :
pool: www
process manager: dynamic
start time: 29/Jul/2025:12:34:56 +0000
start since: 3600
accepted conn: 2134
listen queue: 0
max listen queue: 0
listen queue len: 128
idle processes: 8
active processes: 2
total processes: 10
max active processes: 4
max children reached: 0
slow requests: 0
🔐 Astuce sécurité : restreindre plus strictement l’accès
Pour Apache :
Pour Nginx :
🧼 Autres options utiles
request_terminate_timeout
request_terminate_timeout = 30s
-
Tuer les scripts PHP qui s’exécutent trop longtemps (défense anti boucle infinie, DoS)
rlimit_files et rlimit_core
rlimit_files = 1024
rlimit_core = 0
-
Limite le nombre de fichiers ouverts par processus
-
Empêche le dump mémoire
php_admin_value[memory_limit]
php_admin_value[memory_limit] = 128M
-
Définir une limite mémoire par pool
📋 Fichier exemple complet de pool www.conf
[www]
user = www-data
group = www-data
listen = /run/php/php8.1-fpm.sock
listen.owner = www-data
listen.group = www-data
listen.mode = 0660
pm = dynamic
pm.max_children = 30
pm.start_servers = 10
pm.min_spare_servers = 5
pm.max_spare_servers = 15
pm.status_path = /status
request_terminate_timeout = 30s
rlimit_files = 1024
php_admin_value[memory_limit] = 128M
php_admin_flag[display_errors] = off
📊 Outils utiles pour suivre le comportement PHP-FPM
| Outil | Usage |
|---|---|
top, htop |
Charge système, mémoire |
ps, smem |
RAM par processus PHP |
curl /status |
Charge FPM live |
ngxtop, goaccess |
Suivi des requêtes Nginx/Apache. |
prometheus + exporter. |
Monitoring à grande échelle |
📎 En résumé
| Paramètre | Utilisation |
|---|---|
pm.max_children |
Nombre max de requêtes PHP simultanées |
pm = ondemand |
Sites très légers ou occasionnels |
request_terminate_timeout. |
Tue les scripts trop longs |
memory_limit |
Évite la saturation mémoire par script |
status_path |
Suivi live des processus PHP-FPM |
✅ Conclusion
Un bon tuning PHP-FPM permet de :
-
Gagner en stabilité
-
Réduire la consommation RAM
-
Éviter les goulets d’étranglement
-
S’adapter à la charge réelle