PHP-FPM Production Pool Tuning for High-Traffic Linux Servers
- Author :Liam K.
- Date :June 30, 2026
- Time :16 minutes
PHP-FPM pool misconfiguration is one of the most common causes of 502 errors, memory exhaustion, and unpredictable latency on Linux web servers. The right worker count depends on available RAM, per-request memory footprint, and concurrency — not generic defaults. This guide shows how to size and tune pools for production traffic.
Step 1: Measure Per-Worker Memory
Run your application under realistic load, then measure RSS per PHP-FPM child process.
ps -ylC php-fpm8.3 --sort=rss | awk 'NR==1{print} NR>1 && NR<=15{print}'
# Example output: each worker ~85 MB RSS for a typical Laravel appStep 2: Calculate Safe max_children
Reserve 20–30% RAM for OS, database, cache, and Nginx. Formula: max_children ≈ (available RAM for PHP) / average worker RSS.
# Example: 8 GB RAM server, reserve 2 GB for system + DB + cache
# Available for PHP: 6 GB = 6144 MB
# Worker RSS: 85 MB
# max_children ≈ 6144 / 85 ≈ 72 (use 60–65 for headroom)Step 3: Configure a Dynamic Pool
sudo tee /etc/php/8.3/fpm/pool.d/www.conf >/dev/null <<'EOF'
[www]
user = www-data
group = www-data
listen = /run/php/php8.3-fpm.sock
listen.owner = www-data
listen.group = www-data
listen.mode = 0660
[...]Step 4: Tune OPcache for Production
sudo tee /etc/php/8.3/fpm/conf.d/10-opcache.ini >/dev/null <<'EOF'
opcache.enable=1
opcache.enable_cli=0
opcache.memory_consumption=256
opcache.interned_strings_buffer=32
opcache.max_accelerated_files=20000
opcache.validate_timestamps=0
opcache.revalidate_freq=0
[...]Set opcache.validate_timestamps=0 only when you reload PHP-FPM after each deploy. For development, keep validation enabled.
Step 5: Add Nginx FastCGI Timeouts
# Inside your PHP location block:
fastcgi_connect_timeout 10s;
fastcgi_send_timeout 60s;
fastcgi_read_timeout 60s;
fastcgi_buffers 16 16k;
fastcgi_buffer_size 32k;Step 6: Validate and Reload
sudo php-fpm8.3 -t
sudo systemctl reload php8.3-fpm
sudo systemctl reload nginx
# Watch pool status during load test
watch -n 2 'ps -ylC php-fpm8.3 | wc -l'Step 7: Monitor Slow Requests
sudo tail -f /var/log/php8.3-fpm-slow.log
# Enable php-fpm status page (restrict to localhost):
# pm.status_path = /fpm-status
# ping.path = /fpm-pingCommon Mistakes to Avoid
- Setting
pm.max_childrentoo high — causes OOM kills under traffic spikes. - Using
pm = ondemandfor latency-sensitive APIs without measuring cold-start cost. - Ignoring
pm.max_requests— long-lived workers can leak memory over days. - Deploying code changes without reloading PHP-FPM when OPcache timestamp validation is disabled.
- Running multiple heavy PHP apps in one pool instead of separate pools per site.
"PHP-FPM tuning is arithmetic, not guesswork: measure worker memory, size the pool, then validate under load before you trust it in production."
Technical Author

System administrator and technical writer specializing in server infrastructure, security and deployment. Creating comprehensive guides to help you master server administration.