Optimizing PHP-FPM for Better Performance
PHP-FPM (FastCGI Process Manager) is the standard way to run PHP on modern web servers. A well-configured PHP-FPM setup can make the difference between a slow and a fast website. At Theory7, we often see that default configurations are not optimal for the specific workload. In this guide, you will learn how to correctly configure and optimize PHP-FPM for maximum performance.
What is PHP-FPM?
PHP-FPM manages a pool of PHP worker processes. When a PHP page is requested, one of these workers handles the request. The way workers are managed largely determines the performance of your website. This is crucial, especially for websites with high visitor numbers or intensive applications.
Benefits of PHP-FPM:
- Better resource management than mod_php, allowing your server to use available resources more efficiently.
- Process isolation per website, which increases security and stability.
- Graceful restarts without downtime, which is essential for websites that need to be continuously available.
- Advanced logging options, giving you better insight into performance and potential issues.
Pool Configuration
The pool configuration determines how many PHP processes are running. This file is usually found at:
/etc/php/8.2/fpm/pool.d/www.conf
Replace 8.2 with your PHP version. It is important to adjust this configuration to the specific needs of your application.
Process Manager Modes
PHP-FPM has three modes:
- static - Fixed number of workers
pm = static
pm.max_children = 20
Best for dedicated servers with predictable load. - dynamic - Automatically scales
pm = dynamic
pm.max_children = 50
pm.start_servers = 10
pm.min_spare_servers = 5
pm.max_spare_servers = 20
Best for most situations, especially with fluctuating visitor numbers. - ondemand - Workers only on requests
pm = ondemand
pm.max_children = 50
pm.process_idle_timeout = 10s
Best for servers with low traffic or limited memory.
Calculating max_children
The max_children value depends on your available memory. It is crucial to calculate this value correctly to prevent server overload:
max_children = (Available RAM - Other usage) / Average PHP process size
Example calculation:
- 4 GB RAM server
- 1 GB for OS and database
- Average PHP process: 50 MB
max_children = 3000 MB / 50 MB = 60
Check the average memory usage per PHP process with the following command:
ps --no-headers -o "rss" -C php-fpm | awk '{ sum+=$1 } END { print sum/NR/1024 " MB" }'
Request Limits
Prevent memory leaks by periodically refreshing processes. You can set this with:
pm.max_requests = 500
After 500 requests, a worker will be restarted. This prevents memory growth due to poorly written code, which is crucial for the stability of your application.
php.ini Optimization
In addition to the pool configuration, the php.ini is also important for the performance of your PHP applications.
Memory and Execution Limits
Set the memory and execution limits based on the needs of your application:
memory_limit = 256M
max_execution_time = 300
max_input_time = 300
Adjust these according to your application. For example, WordPress often requires 256M, while large imports require more memory.
Upload Limits
Set the upload limits to ensure your application can handle large files:
upload_max_filesize = 64M
post_max_size = 64M
max_file_uploads = 20
Note: post_max_size must be equal to or greater than upload_max_filesize.
OPcache Configuration
OPcache stores compiled PHP code in memory, which can significantly speed up your application's load time:
opcache.enable = 1
opcache.memory_consumption = 128
opcache.interned_strings_buffer = 16
opcache.max_accelerated_files = 10000
opcache.revalidate_freq = 60
opcache.validate_timestamps = 1
opcache.fast_shutdown = 1
For production, you can set validate_timestamps to 0 for extra speed, but you will need to manually clear OPcache on code changes.
Realpath Cache
To reduce filesystem calls for include/require statements, you can configure the realpath cache:
realpath_cache_size = 4M
realpath_cache_ttl = 600
Applying Configuration
After making changes, you need to restart PHP-FPM to apply the new settings:
# Systemd
sudo systemctl restart php8.2-fpm
# Or for other versions
sudo systemctl restart php7.4-fpm
Test if the configuration is valid with:
sudo php-fpm8.2 -t
Multiple Pools for Multiple Sites
For better isolation, you can create a separate pool for each website. This is especially useful for hosting providers or developers managing multiple projects:
sudo cp /etc/php/8.2/fpm/pool.d/www.conf /etc/php/8.2/fpm/pool.d/mysite.conf
Adjust in mysite.conf:
[mysite]
user = myuser
group = myuser
listen = /run/php/php8.2-fpm-mysite.sock
Configure your web server to use the correct socket for each site, so that each site has its own resources and performs better.
Monitoring PHP-FPM Status
Activate the status page to monitor your PHP-FPM processes:
pm.status_path = /fpm-status
Configure your web server to serve this (only locally):
location /fpm-status {
fastcgi_pass unix:/run/php/php8.2-fpm.sock;
include fastcgi_params;
allow 127.0.0.1;
deny all;
}
Troubleshooting
502 Bad Gateway
This may mean that PHP-FPM is not running or that the socket is misconfigured. Check the status with:
sudo systemctl status php8.2-fpm
Slow Performance
If you notice that performance is slow, check if max_children is set too low. You can do this by checking the logs:
sudo tail -f /var/log/php8.2-fpm.log
Look for messages like "server reached max_children" to see if you need to add more workers.
Memory Errors
If you encounter memory errors, consider increasing memory_limit or optimizing your code to use less memory.
Related Articles
- Server backup strategy
- SSH connection from Mac/Linux
- Basic Linux commands for hosting
- Monitoring server resources
Need Help?
We are here for you! Are you facing any issues or do you have questions? Our support team is happy to assist you personally. Send us a message via the ticket system - we usually respond within a few hours and are happy to help.
0 van 0 vonden dit nuttig