Determining the correct number of child processes for PHP-FPM

Category: Cloud servers

Debian Linux Nginx PHP Apache FPM

You might experience the effects of incorrect child process configuration if your website is having performance issues, high resource usage, or error messages in your php-fpm.log file such as:

[pool www] server reached pm.max_children setting (x), consider raising it
[pool www] seems busy (you may need to increase pm.start_servers, or pm.min/max_spare_servers)

Other examples of common problems that indicate a need for PHP-FPM tuning problems are:

  • Slow website or application performance and delays in processing requests
  • High CPU or memory usage: Too many child processes can overload your server, while too few can lead to slow response time
  • 502/504 Gateway Timeout errors

All these symptoms tell you that you do not have enough room left for requests (child processes) within your PHP-FPM process. Let’s fix that!

Determining the correct number of processes for PHP-FPM

Based on your realtime logging data, it is easy to determine the correct settings for the php-fpm configuration on your server. The exact settings are based on the memory available to your cloud server, but be aware that you also have to take the other processes into account, they also nibble on those resources (examples: MariaDB, MySQL, Redis). Never simply use 100% memory available in the cloud server!

The following steps need to be adjusted in the /etc/php/8.2/fpm/pool.d/www.conf file (typical location on a Linux Debian server, although the path may vary):

pm.max_children = 5
pm.start_servers = 2
pm.min_spare_servers = 4
pm.max_spare_servers = 8

To find the correct values, you will have to measure how much memory a single PHP proces consumes. Be aware! This is only possible on a server where the website has a stable memory usage per process. If the FPM pool is used by multiple websites with different requirements, the memory usage of processes may vary a lot. This will make it difficult to determine the average usage.
The following line (executed in shell) will give you valuable output:

ps -ylC php-fpm8.2 --sort:rss

The name php-fpm8.2 matches your process name. It is possible it has a different name on your server, it depends on the PHP packages used.

You should be able to find the correct process name like this:

ps -e | grep php-fpm

The column RSS contains the average memory usage in kilobytes per process.

S UID PID PPID C PRI NI RSS SZ WCHAN TTY TIME CMD
S 0 24439 1 0 80 0 6364 57236 - ? 00:00:00 php-fpm8.2
S 33 24701 24439 2 80 0 61588 63335 - ? 00:04:07 php-fpm8.2
S 33 25319 24439 2 80 0 61620 63314 - ? 00:02:35 php-fpm8.2

In this example 61588 kilobytes or about +- 60 Mb per process.

Another option is to get the average of one php-fpm process:

ps --no-headers -o "rss,cmd" -C php-fpm8.2 | awk '{ sum+=$1 } END { printf ("%d%s\n", sum/NR/1024,"Mb") }'

Calculating pm.max_children

To get the correct value for the number of pm.max_children we will have to check how much memory our cloud server can use for the php-fpm process and divide that total by the average size in Mb of our just checked process.

An example:

Our cloud server has 4 GB RAM.
We also have a MariaDB database service running on the server. MariaDB uses at least 1 GB of RAM.
That leaves us with 3 GB of RAM, but we need to keep a margin. In this case we take 0.5 GB.

If we take this margin into account we are left with 2560 Mb (or roughly said 2.5 GB of RAM) for our PHP processes.

We divide our free memory by the amount that a PHP process uses. This gives us the maximum amount of processes:

2560 Mb / 60 Mb = 42 processes

So, pm.max_children brings us to 42 max_children
This can be used to update the php-fpm pool configuration file.

We have made the following changes:

pm.max_children = 40
pm.start_servers = 15
pm.min_spare_servers = 15
pm.max_spare_servers = 25
pm.max_requests = 500

Restart the php-fpm82 service and see if the server behaves in a correct manner and allocates memory as configured.

Bonus: by specifying the pm.max_requests you will tell PHP to "recycle" its process after X number of requests (in our case, 500).
This will mean that once the process has passed 500 requests it will be recreated. This can be useful to work around memory leaks in 3rd party libraries.
Or, as explained in the official PHP documentation: The number of requests each child process should execute before respawning.

Do you need help with PHP-FPM optimization or performant hosting?

Configuring the right number of child processes for PHP-FPM is crucial for ensuring your server runs efficiently without performance bottlenecks. Whether you're experiencing slow response times, high resource usage, or frequent errors, proper tuning can make a significant difference.

At Kinamo, we specialize in optimizing hosting environments for peak performance and stability. If you need expert advice on PHP-FPM configuration, managed hosting, or server optimization, our team is here to help. Contact us today to discuss your needs and ensure your hosting environment runs smoothly.


Related articles

Buy an SSL certificate? What is an SSL certificate?

Find out what an SSL certificate is, why it is essential for site security and how easy buying an SSL...

Read more

Create an automatic SPAM filter in the Kinamo Webmail

Do you have an email with Kinamo? Discover here how to create a special filter via Kinamo Webmail to keep...

Read more

Is my e-mail address protected from junk mail or spam?

Kinamo enforces strict anti-spam control. If you're here, you're likely facing spam issues. Learn how we protect our customers.

Read more

Need extra help?

Were not all your questions answered?
Don't worry, we will be happy to help you via a support request!

Kinamo

Select your language

All languages: