4

This is an urgent question. My AWS instance with 4GB RAM and 2vCPU is getting exhausted by too many php-fpm processes.

PHP-FPM starts creating too many processes which it didn't do earlier. This results in slow loading of the site. I'm not able to figure out why this is happening.

My php.ini config:

html errors = off
precision = 14
output_buffering = 4096
serialize_precision = 17
max_execution_time = 300
max_input_time = 60
max_input_vars = 5000
log_errors_max_len = 1024
post_max_size = 27M 
upload_max_filesize = 27M 
max_file_uploads = 20
default_socket_timeout = 60
pdo_mysql.cache_size = 2000
memory_limit = 256M

www.conf:

pm = dynamic
pm.max_children = 35
pm.start_servers = 10
pm.min_spare_servers = 10
pm.max_spare_servers = 20
pm.max_requests = 1000

screenshot of top command: top command output

2 Answers 2

4

Answering your question

In www.conf change this (35 processes)

pm.max_children = 35
pm.start_servers = 10
pm.min_spare_servers = 10
pm.max_spare_servers = 20
pm.max_requests = 1000

to this (8 processes) - or whatever number you like

pm.max_children = 8
pm.start_servers = 4
pm.min_spare_servers = 1
pm.max_spare_servers = 2
pm.max_requests = 1000

You may also like to correct this typo

max_file_uploads = 20 = 20

Answering the question in the comments

As background, pm.max_children is how many PHP threads are available to service requests. If not thread is available a request will queue, up to the web server timeout, until a work is available.

PHP is very memory intensive, and quite CPU intensive. If you have enough RAM (say) 10 PHP threads, but allocate 30, your server will swap and performance will be terrible. If you over-allocated CPU it will go slower, but it won't be as bad as insufficient RAM.

In general, you should work how how many PHP workers can run without exhausting your servers RAM. Let's say your server is using 2GB RAM with PHP turned off, and each thread uses 100MB of RAM, you can have about 20 PHP workers. You should try to avoid saturating RAM, as it's used as a disk cache, so leave some RAM free.

You need to find a balance between slow PHP threads and queuing. No-one can do that for you, it will be experimentation until your server is fully utilized but not struggling. But, to start, let's say a maximum of 10 threads and go from there. Use "top" to monitor free memory, but for memory you may need to use the "res" (resident in memory, I assume) column rather than "virt" to estimate PHP RAM use.

Opcache

I suspect (but don't know for sure) that advice to enable the opcache is outdated, as PHP7 is fairly well optimised and likely enabled by default.

Caching

The key to good performance with PHP is caching. Anonymous users hitting a page that isn't customised can often be cached, even if it's only for 1 / 5 / 60 seconds it can be a big help on a highly loaded server. Make sure your caching headers properly describe the page expiry, then configure Nginx / Apache to cache appropriately - if you're using a web server.

You can also cache static resources on a CDN, such as CloudFront / CloudFlare (note that CloudFlare has a free tier and works well with AWS). It won't say much CPU or RAM, but it will save bandwidth. Every bit helps on a loaded server.

4
  • I've "pm.max_children" as 35 because I kept getting pm.max_children reached consider raising it in php-fpm log. How reducing it to 8 will resolve the problem or how having it as 35 is creating the problem? I've fixed the typo, thank you.
    – Axel
    Jan 13, 2020 at 9:12
  • I would take a look at the web server logs as to what is causing the traffic, rather than simply adjust the php configuration - also do you have php opcache enabled? This would save you lots of cycles due to having php compiled as bytecode.
    – Miuku
    Jan 13, 2020 at 10:05
  • @Miuku can opcache be enabled in a stateless arichitecture? We've multiple servers running and servers are behind a load balancer. Every request goes to a new ec2 instance. In this scenario, is it of any use to have opcache enabled?
    – Axel
    Jan 13, 2020 at 12:32
  • I have expanded my answer to give more background and address your new questions
    – Tim
    Jan 13, 2020 at 18:18
0

I would check what kind of CPU it is that you have. If you're using Graviton Cpus they are 1 to 1 on CPU vs Threads.

ie. the CPU count is what you should have as number pm.max_children. If you're afraid of memory leaks or that its a recurring problem you can always use the pm.max_requests feature and set it to an appropriate value.

That value is somewhat based on how fast you're leak is growing. Too small and you could experience bad gateways from now and then.

You must log in to answer this question.

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