17

I have done some investigations and I have found this to calculate and adjust pm.max_children value

https://myshell.co.uk/blog/2012/07/adjusting-child-processes-for-php-fpm-nginx/

but for example :

  • I have 8Gb on my server
  • I'm hosting 30 websites
  • php-fpm average process size around 40mb
  • php-fpm max process size around 80mb
  • I want to allocate 5Gb max of my memory to php-fpm processes

If I apply this :

pm.max_children = Total RAM dedicated to the web server / Max child process size

So in my case :

pm.max_children = 5120 / 80 = 64

But If I add pm.max_children = 64 on each php-fpm website conf files, this means every website can use 64 children process X size of 1 process (ex 40mb) = 2560Mb

And If we imagine, at the same time, all the 30 website have reach the pm.max_children value, we will have : 2560Mb (max per website) x 30 websites = 76 800 Mb

Am I correct?

Si yes, this means when many websites are hosted on the same server, we have to divide the result of the calcul pm.max_children = 5120 / 80 = 64 by the number of websites hosted (here 30).

So 64 / 30 = 2,1 and pm.max_children = 2 per website

Is it correct or not?

Thanks

4
  • nobody has infos about that? Nov 11, 2018 at 13:12
  • Only if you are using different FPM pool for every website a value of 2 does this. The common approach (because of sharing resources) is to have one FPM pool. Than you can limit it to the higher value if you watch for RAM as a capacity limit. Actually you should have enough CPU to handle 64 concurrent processes as well. Nov 12, 2018 at 4:30
  • hello, thank you for your feedback. for the moment I have 1 pool for all 30 websites. the server has 4 vCPU and 8 Gb of RAM. I don't know if it would be better to have one FPM pool per website or 1 pool for all websites? for maintenance reasons, 1 pool for every website could be interesting. but for performances reasons I don't know. what's your opinion? Nov 12, 2018 at 8:46
  • hello, do you have any advice on how to use php-fpm pools? would it be better to have 1 pool for many websites or 1 pool for every website? thanks Nov 13, 2018 at 9:58

2 Answers 2

15

Your calculation is correct from what I gather.

Having many webs on the same server works only as long as not all webs use all available resources at the same time. This is what people usually call overprovisioning.

However, I suggest not to simply calculate pm.max_children around the available RAM, but around how many workers are actually necessary for the webs to function properly. Start with something lower and monitor the the php-fpm.log. If the max_children setting is reached, you will find it in the log and you can increase it.

Also, make sure that the PHP workers only live as long as necessary. For example, the following configuration will let a pool use up to 32 PHP workers if there is a burst of requests, but each worker will exit after 3 seconds of inactivity and free valuable RAM:

pm = ondemand
pm.max_children = 32
pm.process_idle_timeout = 3s

Use the ondemand process manager if you are low on RAM. It is a bit slower than the dynamic pm, but doesn't waste RAM for inactive websites.

If you want to control the total number of PHP processes, there is a setting called process.max in php-fpm.conf. I have never used it, but it seems to me you could use it to ensure that there are never more than a certain number of workers, regardless of how the pools are configured.

By the way, it is a very good idea to use separate pools for separate webs belonging to separate users. That way you won't have any problems with user permissions or with data cached from other webs.

11
  • Thank you for you feedback. I have for the moment 8 GB of RAM...maybe too short ? yes on demand could be much slower than dynamic, but much more secure indeed. Nov 13, 2018 at 20:05
  • 2
    I think you should just try it and see how it performs. Compare ondemand and dynamic, don't forget that you can also mix them (e.g. dynamic for the busier webs, ondemand for less important ones).
    – Oliver
    Nov 14, 2018 at 7:17
  • ok. I see. About config, I can keep the main config file here /etc/php/7.2/fpm/php-fpm.conf where I set up pm = .... with pm.max_children = .... etc... and I can have 1 pool for every website here /etc/php/7.2/fpm/pool.d/ where I set up for each website a conf file containing user = ... + group = ... + listen =... + listen.owner = ... + listen.group = ... . Am I correct? Nov 14, 2018 at 8:04
  • No idea if it works that way. Usually pm settings are per-pool. Check out the default config files and work from there rather than trying to do something else.
    – Oliver
    Nov 14, 2018 at 9:44
  • I have seen that PM settings are available in this file /etc/php/7.2/fpm/php-fpm.conf but can also be added in this file /etc/php/7.2/fpm/pool.d/example.conf if we use 1 pool per website. but in my case, 1 pool per website will contain only settings for user and group. the PM settings will be global, that's why I want to manage it in this file /etc/php/7.2/fpm/php-fpm.conf . also pm.max_children can be used globally instead of in each pool file no? Nov 14, 2018 at 10:17
4

I can only give you an advise based on our experiences.

We have only one PHP-FPM pool running to share resources (CPU and RAM).

Multiple pools allow different user accounts (e.g. www-data1, www-data2 ...) and may help to restrict access. Additionally you can assign different values for CPU and RAM consumption if required.

However following example uses only one pool:

; www.conf
;
; set pool management to have a fixed number of php workers
pm = static
; number of php processes (6 processes per CPU core)
pm.max_children = 48

I recommend using static pool management. This means there are always a fixed number of PHP workers.

; www.conf
;
; redirect worker stdout and stderr into main error log
catch_workers_output = yes

This might be helpful if your application runs into errors.

; php-fpm.conf
;
emergency_restart_threshold = 10
emergency_restart_interval = 1m
process_control_timeout = 10s

This is some basic life monitoring of your running PHP workers.

Do not forget to restart your PHP-FPM service after these changes.

1
  • many thanks for all these details. Ok so this means I can keep the main config file here /etc/php/7.2/fpm/php-fpm.conf where I set up pm = .... with pm.max_children = .... etc... and I can have 1 pool for every website here /etc/php/7.2/fpm/pool.d/ where I set up for each website a conf file containing user = ... + group = ... + listen =... + listen.owner = ... + listen.group = ... . Am I correct? Nov 13, 2018 at 19:59

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .