Nginx – adjusting php fpm configuration

dedicated-servernginxphp-fpm

Lately my server (i7-2600 @ 4×3.4ghz, 8GB Ram) is getting really high load averages. Ive cached the most popular pages and tried to remove them aswell to test if they are the fault, but it gives no significant changes.

Load average is below 1.0 when I restart my server then suddenly it starts growing and goes to 6.0 – 25.00 and I get 504 gateway timeout errors and ssh is getting really slow and it causes a lot of problems.

I think it has something to do with my php-fpm config, because Ive been using mysqltuner.pl and following the instructions there, also as I said Ive cached and removed for few minutes the most popular pages and they also have heavy queries with left joins etc and that didnt give significant changes I mean the load could drop for about 5%, but thats not what I`m after.

My site gets about 500 unique users every 5 minutes (google analytics real time statistics) and about 5-15 pageviews every second.

So here is my php-fpm config, can anyone suggest what to adjust?

pm = dynamic

pm.max_children = 500

pm.start_servers = 400

pm.min_spare_servers = 50

pm.max_spare_servers = 500

pm.max_requests = 0

Best Answer

It's highly unlikely you have enough RAM to have 500 PHP processes running. On my boxes, they typically take up 40-80MB each depending on what they happen to have been doing.

So what happens here is, when you start PHP, it tries to start 400 copies of itself, as that's what you've specified. But you would need at least twice as much RAM as you currently have! So the machine very quickly starts swapping, and grinds to a halt.

Drop these numbers dramatically, until you are well within the bounds of your memory. You don't need 400 simultaneous processes running to handle 5-15 pageviews per second.

You also should set a value for pm.max_requests in case of memory leaks in PHP or another PHP module that you might be using. These are unfortunately far too common.

To get your server back under control, try starting with:

pm.max_children = 50
pm.start_servers = 10
pm.min_spare_servers = 10
pm.max_spare_servers = 50
pm.max_requests = 500

This gives you plenty of room to process both normal traffic and spikes of up to 5x your normal load. You can raise pm.max_children if you start getting much busier and see log entries about running out of children, but check your free RAM before you do; if you ever get to that point you'll probably have to upgrade the server.