Join our Telegram: @serverrental_wiki | BTC Analysis | Trading Signals | Telegraph
PHP-FPM Optimization Guide
PHP-FPM Optimization Guide
This guide provides practical steps for optimizing PHP-FPM (FastCGI Process Manager) to improve your web server's performance and stability. We will cover key configuration directives, including worker process management, setting appropriate child process limits, enabling and configuring the slow log, and leveraging OPcache for faster PHP execution.
Prerequisites
Before you begin, ensure you have:
- Root or sudo access to your Linux server.
- A working PHP-FPM installation.
- Basic understanding of Linux command-line operations.
- Access to your PHP-FPM configuration file (typically located at `/etc/php/<version>/fpm/php-fpm.conf` or in a directory like `/etc/php/<version>/fpm/pool.d/www.conf`).
Understanding PHP-FPM Process Management
PHP-FPM uses worker processes to handle incoming PHP requests. Efficiently managing these processes is crucial for performance. PHP-FPM offers several process management control methods:
- static: A fixed number of child processes are always kept alive. Good for predictable workloads.
- dynamic: The number of child processes varies between a minimum and maximum based on demand.
- ondemand: Child processes are created only when a request arrives and are killed after a period of inactivity.
For most web servers, the dynamic or ondemand modes offer a good balance between resource utilization and responsiveness.
Configuring Worker Processes (pm.max_children, pm.start_servers, etc.)
The most critical parameters for process management are found within your PHP-FPM pool configuration file. For a dynamic process manager, you'll typically see directives like:
- pm.max_children: The maximum number of child processes that will be spawned at any given time. This is a hard limit and exceeding it can lead to requests being queued or dropped.
- pm.start_servers: The number of child processes to start when PHP-FPM starts.
- pm.min_spare_servers: The minimum number of idle child processes to maintain.
- pm.max_spare_servers: The maximum number of idle child processes to maintain.
To configure these:
- Locate your PHP-FPM pool configuration file. This is often `www.conf` within a pool directory. For example:
/etc/php/8.1/fpm/pool.d/www.conf
- Open the file with a text editor (e.g., `nano` or `vim`):
sudo nano /etc/php/8.1/fpm/pool.d/www.conf
- Find and adjust the `pm` directive and related settings. For example, to use dynamic process management:
pm = dynamic pm.max_children = 100 pm.start_servers = 10 pm.min_spare_servers = 5 pm.max_spare_servers = 20 pm.max_requests = 500
- pm.max_requests: The number of requests each child process will execute before respawning. Setting this can help prevent memory leaks in long-running scripts.
- Save the file and exit the editor.
- Restart PHP-FPM to apply the changes:
sudo systemctl restart php8.1-fpm
Determining `pm.max_children`: A common formula to estimate `pm.max_children` is:
pm.max_children = (Total RAM - RAM used by OS/other services) / Average RAM per PHP-FPM child process
You can estimate the average RAM per child process by monitoring your system under load. Start with a conservative value and increase it gradually while monitoring server resource usage.
Enabling and Configuring the Slow Log
The slow log is an invaluable tool for identifying PHP scripts that are taking too long to execute. This can point to inefficient code, database queries, or external API calls.
- In your PHP-FPM pool configuration file (e.g., `/etc/php/8.1/fpm/pool.d/www.conf`), find or add the following directives:
request_slowlog_timeout = 5s slowlog = /var/log/php/php-fpm-slow.log
- request_slowlog_timeout: The time in seconds after which a script is considered "slow" and logged.
- slowlog: The path to the slow log file. Ensure the directory exists and PHP-FPM has write permissions.
- Create the log directory if it doesn't exist and set appropriate permissions:
sudo mkdir -p /var/log/php
sudo chown www-data:www-data /var/log/php
(Replace `www-data` with your PHP-FPM user if different.)
- Restart PHP-FPM:
sudo systemctl restart php8.1-fpm
- Monitor the slow log for entries:
sudo tail -f /var/log/php/php-fpm-slow.log
When slow requests appear, examine the output to identify the specific script and line number causing the delay.
Leveraging OPcache
OPcache is a PHP extension that stores precompiled script bytecode in shared memory, eliminating the need for PHP to load and parse scripts on every request. This significantly speeds up PHP execution.
- Check if OPcache is enabled:
php -m | grep opcache
If `Zend OPcache` is listed, it's enabled.
- If not enabled, install it:
sudo apt update && sudo apt install php8.1-opcache
(Adjust package name for your PHP version.)
- Configure OPcache by editing your `php.ini` file. The location varies but is often found at:
/etc/php/8.1/fpm/php.ini
- Open the file:
sudo nano /etc/php/8.1/fpm/php.ini
- Find and adjust these common OPcache settings:
opcache.enable=1 opcache.memory_consumption=128 ; In MB opcache.interned_strings_buffer=16 opcache.max_accelerated_files=10000 opcache.revalidate_freq=60 opcache.validate_timestamps=1 ; Set to 0 in production for maximum performance if you manually clear cache on deploy opcache.save_comments=1 opcache.enable_cli=1 ; Optional, for CLI scripts
- Save the file and exit.
- Restart PHP-FPM and your web server (e.g., Nginx or Apache):
sudo systemctl restart php8.1-fpm
sudo systemctl restart nginx
(Or `sudo systemctl restart apache2` for Apache.)
Troubleshooting
- PHP-FPM not starting: Check system logs (`sudo journalctl -xeu php8.1-fpm`) for specific error messages. Common issues include syntax errors in configuration files or permission problems with log directories.
- Requests are slow or timing out:
* Check the slow log for offending scripts. * Increase `pm.max_children` if your server has sufficient RAM and is CPU bound by PHP processes. * Optimize your PHP code and database queries. * Ensure OPcache is properly configured and enabled.
- High CPU or RAM usage:
* Reduce `pm.max_children`. * Investigate runaway scripts identified by the slow log. * Consider using a more efficient process manager like `ondemand` if your traffic is spiky.
- OPcache not working:
* Verify `opcache.enable=1` in `php.ini`. * Ensure the `php8.1-opcache` module is loaded. * Check PHP error logs for any OPcache-related warnings.
Further Reading
This guide provides a solid foundation for optimizing PHP-FPM. Remember to monitor your server's performance after making changes and adjust settings iteratively for the best results.