PHP-FPM settings tutorial. max_servers, min_servers, etc.

The other day, I was looking around for articles and tips on how to fine tune PHP FPM’s www.conf settings.

To my frustration, the official documentation didn’t give any recommendations. Furthermore, there weren’t a lot of tutorials on the subject.

After wading through various discussions and blog posts, I managed to piece together the following information.

You need to know three things about your server before you change PHP FPM’s settings.

  1. How many cores does your server have?
  2. The amount of memory (RAM) on your server.
  3. How much memory does the average PHP process consume on your server?

How many cores does your server have?

To find out how many cores your server has, run the following command:

echo Cores = $(( $(lscpu | awk '/^Socket/{ print $2 }') * $(lscpu | awk '/^Core/{ print $4 }') ))

When you run the Linux command above, you will get something like “Cores = 4”.

Write that figure down because it’s important.

How much memory does your server have?

You should already know how much memory your server has.

The real question here is: How much memory do you want to give PHP?

You have to take into account the fact that your server might also be running NGINX, Apache, or MySQL. How much memory are these other processes consuming? If you have 8GB of RAM and the other processes on your machine are consuming 2GB, that leaves you with 6GB.

Or 5GB if you want to play it safe and leave some free.

Determine how much memory you want to give PHP and jot that down. In my case, I had 4GB that I could allocate to PHP.

On average, how much memory does each PHP process consume?

This will depend on your application and your version of PHP. Older versions of PHP tend to consume more memory than PHP 7.

Run the command below to get a general idea of how much memory each PHP FPM process is consuming.

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

Note that the command above is looking for a process called php-fpm7.2. The PHP process on your server might be called something different.

To find out the name of your PHP process, use the top command. When you run the top command, you will probably see one of the following processes:

  • php-fpm
  • php5-fpm
  • php7.0-fpm
  • php7.1-fpm
  • php7.2-fpm

When I ran the command above, I got 29M.

In other words, each php-fpm7.2 process on my server consumes about 29MB of RAM.

The configuration settings.

I now have three important pieces of information.

  • My server has 4 cores.
  • I can allocate about 4GB of RAM to PHP.
  • Each PHP FPM process on my server consumes about 29MB of memory. On older versions of PHP, you will probably see that each process consumes a lot more than that. I was reaching about 90MB per process when I was running the exact same application on PHP 5.5.

Now it is time to edit the www.conf file, which is located in the pool.d directory. On my server, it was located at:

/etc/php/7.2/fpm/pool.d/www.conf

On your machine, the location might be slightly different.

There are 4 configuration values that we are going to change in the www.conf file:

  • pm.max_children
  • pm.start_servers
  • pm.min_spare_servers
  • pm.max_spare_servers

pm.max_children

To get a good value for this, you should take the memory that you want to allocate to PHP FPM and divide it by the average memory that is consumed by each PHP FPM process.

In my case, I want to allocate 4GB (4000MB) and each process consumes about 29MB.

Divide 4000 by 29 and you get around 138.

So I set pm.max_children to 138.

If you have 8000MB to spare and your PHP consumes about 80MB per process, then that will be: 8000 / 80 = 100.

pm.start_servers

For pm.start_servers, I multiply the number of cores that I have by 4.

4 x 4 = 16

So I set pm.start_servers to 16.

If you have 8 cores, then it will be: 4 x 8 = 32.

pm.min_spare_servers

For pm.min_spare_servers, multiply the number of cores that you have by 2.

In my case, that is 2 x 4 = 8.

So I set pm.min_spare_servers to 8.

pm.max_spare_servers

For pm.max_spare_servers, multiply the number of cores on your server by 4.

On my machine, that is 4 x 4 = 16.

So I set pm.max_spare_servers to 16, the same value that I used for pm.start_servers.

Restart PHP FPM.

For these changes to take effect, you will need to restart PHP FPM.

Below, I have included a number of service restart commands that might apply to your setup. Select the correct one and run it.

sudo service php-fpm restart   
sudo service php5-fpm restart   
sudo service php7.0-fpm restart
sudo service php7.1-fpm restart
sudo service php7.2-fpm restart
sudo service php7.3-fpm restart
sudo service php7.4-fpm restart