
Understanding PHP-FPM Pool Configuration
PHP-FPM (FastCGI Process Manager) sits between your web server and PHP applications, managing worker processes that handle requests. Poor configuration creates bottlenecks that slow response times and waste server resources.
Three process management modes form the core of any PHP-FPM performance tuning tutorial. Dynamic mode spawns workers based on demand. Static mode runs a fixed number of processes. Ondemand mode starts processes only when needed.
Each mode suits different workloads. A busy WordPress site benefits from static mode's predictable resource usage. Development servers work well with ondemand to conserve memory.
Calculating Optimal Worker Process Counts
Your server's available RAM determines how many PHP-FPM workers you can run effectively. Each worker consumes memory based on your application's requirements.
Check current PHP process memory usage:
ps aux | grep 'php-fpm' | awk '{sum+=$6} END {print "Total PHP-FPM memory: " sum/1024 " MB"}'
For a typical WordPress site, each worker uses 30-50MB. On a 4GB VPS with 2GB allocated to PHP-FPM, you can safely run 40-60 workers. Conservative calculations prevent memory exhaustion under traffic spikes.
Monitor actual memory usage over several days before finalizing worker counts. Peak traffic periods reveal real resource needs.
Static Pool Configuration for High-Traffic Sites
Static pools work best for consistent traffic patterns. Configure your pool in /etc/php/8.2/fpm/pool.d/www.conf (adjust path for your PHP version):
[www]
user = www-data
group = www-data
listen = /run/php/php8.2-fpm.sock
listen.owner = www-data
listen.group = www-data
pm = static
pm.max_children = 50
pm.start_servers = 50
pm.min_spare_servers = 25
pm.max_spare_servers = 35
pm.max_requests = 500
Set pm.max_children based on your memory calculations. The pm.max_requests setting forces worker recycling to prevent memory leaks.
Static pools consume more memory but deliver consistent performance. Your managed VPS hosting environment benefits from this predictability during traffic surges.
Dynamic Pool Tuning for Variable Workloads
Dynamic pools adapt to changing traffic patterns. They're ideal for sites with unpredictable visitor patterns or multiple applications sharing resources.
[www]
pm = dynamic
pm.max_children = 50
pm.start_servers = 5
pm.min_spare_servers = 3
pm.max_spare_servers = 10
pm.process_idle_timeout = 60s
pm.max_requests = 500
The key metrics here control scaling behavior. pm.start_servers defines initial workers. pm.min_spare_servers and pm.max_spare_servers set the range for idle workers.
Fine-tune pm.process_idle_timeout based on your traffic patterns. Shorter timeouts save memory but increase CPU overhead from frequent process creation.
Memory and Resource Limit Optimization
PHP-FPM inherits PHP's memory limits, but you can override them per pool. Set appropriate limits in your pool configuration:
php_admin_value[memory_limit] = 256M
php_admin_value[max_execution_time] = 300
php_admin_value[max_input_vars] = 3000
php_admin_value[post_max_size] = 64M
php_admin_value[upload_max_filesize] = 64M
WordPress sites handling media uploads need higher memory limits. WooCommerce stores with large product catalogs require more input variables.
Monitor your application's actual needs through PHP error logs. Adjust limits incrementally rather than setting excessive values that waste resources.
OPcache Integration and Configuration
OPcache stores compiled PHP bytecode in memory, eliminating repeated compilation overhead. Configure it in /etc/php/8.2/fpm/conf.d/10-opcache.ini:
opcache.enable=1
opcache.enable_cli=1
opcache.memory_consumption=256
opcache.interned_strings_buffer=16
opcache.max_accelerated_files=10000
opcache.revalidate_freq=60
opcache.fast_shutdown=1
Size the opcache.memory_consumption based on your codebase. Large WordPress installations with many plugins need 256-512MB. Simple applications work with 128MB.
Set opcache.max_accelerated_files above your total PHP file count. Check with: find /var/www -name "*.php" | wc -l
Monitoring Pool Performance and Health
PHP-FPM includes built-in monitoring through status pages. Enable them in your pool configuration:
pm.status_path = /fpm-status
ping.path = /fpm-ping
Configure Nginx to serve these endpoints:
location ~ ^/(fpm-status|fmp-ping)$ {
access_log off;
allow 127.0.0.1;
deny all;
fastcgi_pass unix:/run/php/php8.2-fpm.sock;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
Monitor key metrics through curl http://localhost/fpm-status?full. Watch for queue length spikes and slow requests that signal configuration problems.
Our Nginx caching configuration tutorial shows how to combine FastCGI caching with PHP-FPM for maximum performance.
Process Priority and Nice Values
Adjust PHP-FPM process priority to balance performance with system stability. Lower nice values give higher priority but can starve other processes.
Add to your pool configuration:
process.priority = -10
Use values between -19 (highest priority) and 19 (lowest priority). For production web servers, -5 to -10 works well without disrupting system processes.
Monitor system load after priority changes. High-priority PHP processes can cause unresponsive SSH connections if overused.
Log Configuration and Error Tracking
Proper logging helps identify performance bottlenecks and configuration issues. Configure detailed logging in your pool:
catch_workers_output = yes
php_admin_value[log_errors] = on
php_admin_value[error_log] = /var/log/php8.2-fpm-www.log
slowlog = /var/log/php8.2-fpm-slow.log
request_slowlog_timeout = 10s
The slow log captures requests exceeding your timeout threshold. Analyze these logs to identify poorly performing code or database queries.
Rotate logs regularly to prevent disk space issues:
/var/log/php*-fpm*.log {
weekly
missingok
rotate 12
compress
delaycompress
notifempty
create 644 www-data www-data
}
Advanced Tuning for Specific Applications
Different applications need specific configurations. WordPress benefits from higher memory limits and longer execution times for plugin operations.
Create separate pools for different applications:
# WordPress pool
[wordpress]
listen = /run/php/php8.2-fpm-wordpress.sock
pm = static
pm.max_children = 40
php_admin_value[memory_limit] = 256M
# API pool
[api]
listen = /run/php/php8.2-fpm-api.sock
pm = dynamic
pm.max_children = 20
php_admin_value[memory_limit] = 128M
php_admin_value[max_execution_time] = 30
Point different virtual hosts to appropriate pools in your web server configuration. This isolation prevents one application from affecting others.
Check our WordPress security hardening tutorial for additional performance and security configurations.
Testing and Validation
Validate your configuration before deploying to production. Test syntax with:
sudo php-fpm8.2 -t
Load test your configuration with realistic traffic patterns. Use tools like Apache Bench or wrk:
ab -n 1000 -c 10 http://your-site.com/
Monitor system resources during tests. Watch for memory exhaustion, high load averages, or process queue buildup.
Compare response times before and after configuration changes. Document baseline performance metrics for future reference.
Ready to optimize your PHP applications with professional hosting? HostMyCode's managed VPS hosting includes pre-optimized PHP-FPM configurations and expert support. Our team handles the complex tuning while you focus on your applications.
Frequently Asked Questions
How many PHP-FPM workers should I run on a 2GB VPS?
For a 2GB VPS running WordPress, allocate 1GB to PHP-FPM and run 20-30 workers. Each worker typically uses 30-50MB. Monitor actual memory usage and adjust based on your specific applications and traffic patterns.
Should I use static or dynamic process management?
Use static mode for consistent high-traffic sites that need predictable performance. Choose dynamic mode for variable traffic or shared hosting environments where memory conservation matters more than consistent response times.
Why do my PHP processes keep getting killed?
Process killing usually signals memory exhaustion. Reduce pm.max_children, increase server RAM, or optimize your application's memory usage. Check system logs for OOM (out of memory) messages to confirm the cause.
How often should I restart PHP-FPM?
Well-configured pools rarely need manual restarts. The pm.max_requests setting handles automatic worker recycling. Only restart when deploying new code or changing configuration files.