TL;DR: To calculate your pm.max_children settings using my calculator, please click here.
For those of us who use php-fpm (Fast Process Manager), one thing you may come across in your production environment as your site or app starts to receive more and more traffic is a warning related to the pm.max_children settings in your PHP error logs.
WARNING: [pool www] server reached pm.max_children setting (5), consider raising it
While most of the time these warnings are not a sign of a serious problems, don't just ignore it - especially if the site or app is going to continue to grow it's traffic.
What's this pm.max_children thing all about anyway?
The pm in pm.max_children refers to PHP FPM's Process Manager so, simply put, the pm.max_children setting limits how many requests can be served by PHP simultaneously.
The first thing to do is check your error log to see what's going on. To do this, it will depend somewhat on your php version. Here are a few standard paths from Ubuntu / Debian systems to the php-fpm error log, but depending on the version you're running, you might have to dig around to find it in the /var/log directory.
//PHP 5.0 tail -f /var/log/php5-fpm.log //PHP 7.0 sudo tail -f /var/log/php7.0-fpm.log //PHP 7.1 sudo tail -f /var/log/php7.1-fpm.log //PHP 7.2 sudo tail -f /var/log/php7.2-fpm.log
Alternately, if you can't find the log, you may need to set up a phpinfo file on your server to figure out where your errors and being logged.
How do I figure out what the optimal number of processes should be for PHP-FPM?
Let's start by taking a look at the settings defined by default in your php-fpm configuration. Start by opening the configuration file in vim (or your favourite text editor) as the root user or by using the sudo command under your own username:
sudo vi /etc/php/7.0/fpm/pool.d/www.conf
You will likely see something similar to the following default settings:
pm.max_children = 5 pm.start_servers = 2 pm.min_spare_servers = 4 pm.max_spare_servers = 8
How do I calculate the pm.max_children settings?
First we need to check how much memory the average process is using, in order to calculate how many processes we can run with the available RAM on our server. To do this, run the following
ps (process status) command which will pull up a list of processes currently running on your server:
ps -ef | grep '[f]'pm //Results on this machine : root 4073 1 0 Sep19 ? 00:02:02 php-fpm: master process (/etc/php/7.0/fpm/php-fpm.conf) www-data 24905 4073 1 18:14 ? 00:00:29 php-fpm: pool www www-data 25056 4073 1 18:30 ? 00:00:11 php-fpm: pool www www-data 25125 4073 1 18:32 ? 00:00:09 php-fpm: pool www
Next, to see the memory that is required for these processes we need to add the
rss parameter which is the 'Resident Set Size' or the physical memory that is being occupied in the physical memory. Note: change php-fpm7.0 to match your version of PHP:
ps -C php-fpm7.0 -o rss= //Results on this machine : 21080 92892 91272 90816
Generally, the first line in this list shows the master process, that in this case is running PHP, and the following results show the resources being used by each child process. These numbers are in Kilobytes so in this example, I would ignore the first process and round up to set an average of 100mb of physical memory per child process.
[Total Available RAM] - [Reserved RAM] - [10% buffer] = [Available RAM for PHP]
[Available RAM for PHP] / [Average Process Size] = [max_children]
pm.max_children = [max_children]
pm.start_servers = [25% of max_children]
pm.min_spare_servers = [25% of max_children]
pm.max_spare_servers = [75% of max_children]