How to Change the PHP-FPM max_children Setting
How to Change the PHP-FPM max_children Setting
The max_children setting limits the maximum number of simultaneously executing PHP requests an app is allowed to have. This limit provides a safeguard against slow or buggy PHP scripts causing your server to run out of memory. It is called max_children because a separate PHP child process is required for each concurrently executing PHP request.
The default max_children setting is 20. This is more than enough for almost all apps.
Important: max_children is not the number of simultaneous visitors your app can have. The number of simultanous visitors is much higher than the max_children setting. See below to learn more about estimating how many site visitors you can have for a given max_children setting.
What Happens When the max_children Limit Is Reached
If an app's PHP scripts can't answer requests as quickly as new requests come in, then PHP-FPM (the PHP FastCGI Process Manager) will launch additional PHP processes for the app to answer requests in parallel. If requests are still coming in faster than the PHP scripts can answer them, PHP-FPM will continue launching additional PHP processes for the app.
PHP-FPM will stop launching additional PHP processes for the app once the number of PHP processes for the app reaches max_children. At that point, additional requests will be queued by PHP-FPM and will only be answered once an existing request completes.
What Causes Apps to Reach the max_children Limit
In the vast majority of cases, an app will only reach the max_children limit if there is slow PHP code in the app, so if your app has reached the max_children limit, you need to first fix any slow PHP code.
To look for slow PHP code, you can start by checking the app's PHP slow request log. The PHP slow request log will show you information about requests that took more than five seconds to complete.
Important to note, however, is that the PHP slow request log will only show extremely slow requests (taking longer than five seconds), not generally slow requests (taking up to five seconds). If you don't see much in the PHP slow request log, you should check the app's PHP access log to understand what scripts are being requested and how long they are taking to respond.
If your app does have slow PHP code, you should resolve the slow code issues before increasing the app's max_children setting.
Identifying the max_children Limit Being Reached
To determine if any of your apps are hitting the max_children limit, SSH in to your server as root and run the following command:
sudo grep max_children /var/log/php?.?-fpm-sp.log.1 /var/log/php?.?-fpm-sp.log
If any of your apps have reached their max_children limit, you'll see output like this:
[24-Apr-2017 19:56:17] WARNING: [pool my-wordpress-app] server reached max_children setting (20), consider raising it
If you don't see any output from the command, then your apps have not hit a max_children limit recently.
Estimating a Value for max_children
The max_children setting is not the number of simultaneous visitors your site can have. Instead, it is the number of simultaneously executing PHP requests. Since site visitors normally only make a request every few seconds and PHP execution time is a small part of the total time it takes a request to complete when there are no slow PHP scripts, the number of visitors your app can have is many, many times larger than the max_children setting of your app.
You can use the following formula to estimate a value of max_children that is sufficient for your app:
max_children = (average PHP script execution time) * (PHP requests per second)
You can estimate how many site visitors you can have for a given max_children setting by knowing your average script execution time and how often a site visitor clicks a link or submits a form.
visitors = max_children * (seconds between page views) / (avg. execution time)
Example
Each visitor to your site clicks one link or submits one form every ten seconds. Each requested PHP script takes 10ms to execute from the time PHP receives the request to the time PHP is done generating the response for the web server server to send back.
20 * 10 / 0.01 = 20,000 ^ ^ ^ | | | | | └ Average request time in seconds (0.01s is 10ms) | └ Average seconds between page view for an individual visitor └ max_children setting
So, with a max_children of 20, this app can support up to 20,000 visitors at a time.
From this example, you can see how important fast PHP script execution is. If each PHP request instead took 2 seconds to execute, the app would only be able to support 100 visitors on the site at a time.
Risks of Increasing max_children
The main risk of increasing max_children is that each additional PHP process uses additional memory, so your server needs more memory as you increase max_children.
The amount of memory used by each executing PHP process depends heavily on the app's PHP code. For WordPress apps, this includes the code of the plugins and theme.
If your PHP scripts are very CPU-heavy, your server's CPU load may also go up after increasing an app's max_children setting.
Also, remember that if you have very slow scripts, no setting of max_children will make your site work normally. Increasing max_children when you have slow scripts means, at best, that each request doesn't have to wait for other slow requests to complete before its own slow execution begins. If there are slow scripts, you still need to fix the slow scripts even if you choose to increase max_children.
Changing max_children
Before proceeding, learn more about customizing PHP settings.
To increase the max_children setting for an app, SSH in to your server as root and rename this file:
/etc/phpX.Y-sp/fpm-pools.d/APPNAME.d/main.conf
to this:
/etc/phpX.Y-sp/fpm-pools.d/APPNAME.d/main.custom.conf
Next, edit the file and change the value on this line to the maximum number of PHP processes you want the app to be able to have running:
pm.max_children = 20
Finally, restart that PHP version with the command:
sudo service phpX.Y-fpm-sp restart