Back to site

Optimize PHP-FPM

Tune PHP-FPM pools on a HolyCloud VPS: dynamic pm, memory, slowlog, OPcache, and Nginx or Apache integration.

Optimize PHP-FPM

PHP-FPM (FastCGI Process Manager) runs PHP in separate processes from the web server, improving stability and performance on a HolyCloud Linux VPS. This guide adjusts the www pool, dynamic worker management, OPcache, slow logs, and integration with Nginx or Apache.

Prerequisites

  • HolyCloud VPS with PHP-FPM installed (php8.2-fpm or php8.3-fpm)
  • Nginx or Apache already configured to pass .php to the FPM socket
  • Approximate available RAM (free -h)
  • sudo access
  • Test site or real traffic to validate settings

Tip: Estimate ~30–80 MB RAM per PHP worker depending on your application; do not exceed physical RAM.

Step 1: Identify version and pool

php -v
systemctl status php8.2-fpm 2>/dev/null || systemctl status php8.3-fpm
ls /etc/php/
ls /run/php/

Default pool file (adapt version):

sudo nano /etc/php/8.2/fpm/pool.d/www.conf

Backup:

sudo cp /etc/php/8.2/fpm/pool.d/www.conf /etc/php/8.2/fpm/pool.d/www.conf.bak.$(date +%F)

Step 2: pm mode and worker count

In [www]:

pm = dynamic
pm.max_children = 20
pm.start_servers = 4
pm.min_spare_servers = 2
pm.max_spare_servers = 6
pm.max_requests = 500

Indicative formula for pm.max_children:

max_children ≈ (RAM available for PHP) / average memory per request

Measure script memory:

ps -o rss,cmd -C php-fpm8.2 | head -10

Small 2 GB VPS (light WordPress site):

pm.max_children = 10
pm.start_servers = 2
pm.min_spare_servers = 1
pm.max_spare_servers = 4

Step 3: slowlog and timeouts

sudo nano /etc/php/8.2/fpm/pool.d/www.conf
request_slowlog_timeout = 5s
slowlog = /var/log/php8.2-fpm-slow.log
request_terminate_timeout = 120s
sudo touch /var/log/php8.2-fpm-slow.log
sudo chown www-data:www-data /var/log/php8.2-fpm-slow.log

Step 4: OPcache (production)

sudo nano /etc/php/8.2/mods-available/opcache.ini
opcache.enable=1
opcache.memory_consumption=128
opcache.interned_strings_buffer=16
opcache.max_accelerated_files=10000
opcache.validate_timestamps=0

validate_timestamps=0 maximizes performance but requires FPM reload after code deployment:

sudo systemctl reload php8.2-fpm

In development, keep validate_timestamps=1.

Step 5: php.ini — reasonable limits

sudo nano /etc/php/8.2/fpm/php.ini
memory_limit = 256M
upload_max_filesize = 64M
post_max_size = 64M
max_execution_time = 120
realpath_cache_size = 4096k

Step 6: Nginx integration (excerpt)

sudo nano /etc/nginx/sites-available/exemple.fr
location ~ \.php$ {
    include snippets/fastcgi-php.conf;
    fastcgi_pass unix:/run/php/php8.2-fpm.sock;
    fastcgi_read_timeout 120;
}
sudo nginx -t && sudo systemctl reload nginx

Step 7: status and ping (local monitoring)

In www.conf (restrict to localhost):

pm.status_path = /fpm-status
ping.path = /fpm-ping

Nginx:

location ~ ^/(fpm-status|fpm-ping)$ {
    access_log off;
    allow 127.0.0.1;
    deny all;
    include fastcgi_params;
    fastcgi_pass unix:/run/php/php8.2-fpm.sock;
}
curl http://127.0.0.1/fpm-ping
curl http://127.0.0.1/fpm-status?full
sudo systemctl restart php8.2-fpm

Verification

php -i | grep -E 'opcache.enable|memory_limit'
ps aux | grep php-fpm | wc -l
free -h
ab -n 100 -c 10 http://127.0.0.1/ 2>/dev/null | tail -5

Under load, RAM must not saturate (dmesg | grep -i oom) and response times should stay stable.

HolyCloud support

  • 502 Bad Gateway: wrong FPM socket (ls /run/php/), FPM service stopped
  • Saturated workers: increase pm.max_children or optimize code; check slowlog
  • OPcache not updating: FPM reload or validate_timestamps=1
  • HolyCloud support: free -h, www.conf excerpt, tail slowlog, PHP version