PHP-FPM sur VPS Performance
PHP-FPM exécute les scripts PHP en processus séparés du serveur web. Sur un VPS Performance HolyCloud, un pool mal dimensionné provoque des 502 (épuisement des workers) ou une RAM saturée (trop de max_children).
Prérequis
- VPS avec Nginx ou Apache + PHP-FPM (ex. PHP 8.2/8.3)
- Accès sudo et connaissance du chemin du pool (
/etc/php/8.x/fpm/pool.d/) - Estimation mémoire par worker (voir ci-dessous)
- Site de test ou staging pour valider sous charge
Localiser la configuration
php-fpm8.3 -tt 2>/dev/null | head
ls /etc/php/8.3/fpm/pool.d/
sudo nano /etc/php/8.3/fpm/pool.d/www.conf
Pool typique [www] :
[www]
user = www-data
group = www-data
listen = /run/php/php8.3-fpm.sock
pm = dynamic
pm.max_children = 20
pm.start_servers = 4
pm.min_spare_servers = 2
pm.max_spare_servers = 6
pm.max_requests = 500
Calculer pm.max_children
Formule de départ :
max_children ≈ (RAM disponible pour PHP) / (mémoire moyenne par worker)
Mesurez la mémoire d'un worker sous charge réelle :
ps -o rss,cmd -C php-fpm8.3 | awk '{sum+=$1} END {print sum/NR/1024 " MB moyenne"}'
Exemple : VPS 8 Go RAM, OS + MySQL + Redis ≈ 3 Go restants pour PHP, worker ~80 Mo :
5120 Mo / 80 Mo ≈ 64 → commencez à 40–50 et montez progressivement
Modes pm : lequel choisir ?
| ------ | ------- |
|---|---|
dynamic |
Défaut web — équilibre latence / RAM |
ondemand |
Trafic très sporadique — démarrage plus lent |
static |
Trafic constant, prévisibilité maximale — RAM fixe |
Production e-commerce fréquent :
pm = dynamic
pm.max_children = 48
pm.start_servers = 8
pm.min_spare_servers = 8
pm.max_spare_servers = 16
Timeouts et files d'attente
request_terminate_timeout = 120s
request_slowlog_timeout = 5s
slowlog = /var/log/php8.3-fpm-slow.log
Évitez request_terminate_timeout = 0 (illimité) — un script bloqué monopolise un worker.
Opcache (indispensable)
Fichier /etc/php/8.3/mods-available/opcache.ini :
opcache.enable=1
opcache.memory_consumption=256
opcache.max_accelerated_files=20000
opcache.validate_timestamps=0
validate_timestamps=0en production après déploiement contrôlé ; remettez1en dev.
Redémarrage :
sudo systemctl restart php8.3-fpm
Nginx : passerelle vers le socket
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/run/php/php8.3-fpm.sock;
fastcgi_buffers 16 16k;
fastcgi_buffer_size 32k;
fastcgi_read_timeout 120s;
}
Vérification sous charge
# statut FPM (si pm.status_path activé)
curl -s http://127.0.0.1/status?full
# logs
sudo tail -f /var/log/php8.3-fpm.log
Test HTTP léger :
hey -n 1000 -c 50 https://votre-site.tld/
Surveillez pendant le test :
watch -n1 'ps -C php-fpm8.3 | wc -l; free -h'
Tuning avancé
; évite les fuites longues
pm.max_requests = 1000
; process manager — ping pour healthcheck
pm.status_path = /fpm-status
ping.path = /fpm-ping
Protégez /fpm-status par IP ou auth Nginx.
Dépannage
| ---------- | -------- |
|---|---|
| 502 Bad Gateway | Workers épuisés → augmenter max_children ou optimiser code |
| Swap qui monte | Réduire max_children, activer Redis cache |
| CPU 100 % PHP | Profiler (Xdebug off en prod), cache objet |
| Slowlog rempli | Requêtes SQL, boucles, appels API synchrones |
Besoin d'aide ?
Joignez au support : extrait www.conf, free -h, extrait slowlog (sans données clients sensibles) et plan VPS Performance.