PHP-FPM Tuning: Using ‘pm static’ for Maximum Performance

Let’s look at how best to set up PHP-FPM for higher throughput, lower latency, and more stable CPU and memory usage. By default, most setups have PHP-FPM’s PM (Process Manager) string set dynamic And there is also general advice to use on demand If you are suffering from available memory problems. However, let’s compare the two management options based on’s documentation and compare my favorites for high traffic setups… Stable pm:

noon = dynamic – The number of child processes is determined dynamically based on the following instructions: pm.max_children, pm.start_server, pm.,

noon = demand – Processes are spawned on-demand (when requested, as opposed to dynamic, where pm.start_servers are started when the service is started.

pm = stable – The number of child processes is decided by pm.max_children,

see Complete list of global php-fpm.conf directives for more information.

PHP-FPM Process Manager (PM) Similar to CPUFreq Governor

Now, this may sound a bit off topic, but I hope to tie it back to our PHP-FPM tuning topic. Well, we all have slow CPU issues at some point be it laptops, VMs or dedicated servers. Remember CPU frequency scaling? (CPUFreq governor) Available on both *nix and Windows, these settings can improve performance and system responsiveness by changing the CPU governor setting. on demand To a demonstration, This time, compare the details and see the similarities:

Governor = demand – Dynamically scales CPU frequency according to current load. jumps to the highest frequency and then decreases as the idle time increases.

governor = conservative = Dynamically measures the frequency according to the current load. Measures frequency more slowly than demand.

Governor = performance – Always run CPU at maximum frequency.

full view List of CPUFreq governor options for more information.

Notice the similarities? I wanted to use this comparison first, with the aim of finding the best way to write an article that recommends using pm stable For PHP-FPM as your first choice.

With CPU Governor, a demonstration The setting is a very safe performance boost as it is almost entirely dependent on the limits of your server CPU. The only other factors would be heat, battery life (laptop), and other side effects of permanently limiting your CPU frequency to 100%. Once set to Performance, this is actually the fastest setting for your CPU. For example, read about the ‘force_turbo’ setting on the Raspberry Pi which forces your RPi board to use this a demonstration Governors where the performance improvement is more noticeable due to lower CPU clock speeds.

Using ‘pm static’ to maximize your server performance

php-fpm pm stable The setting largely depends on how much free memory your server has. Basically, if you are suffering from low server memory, pm on demand either dynamic Might be a better option. On the other hand, if you have memory available, you can avoid PHP Process Manager (PM) overhead by setting pm Stable Up to the maximum capacity of your server. In other words, when you do the math, pm stable PHP-FPM must be set to the maximum amount of processes that can run without creating memory availability or cache pressure issues. Also, not high enough to overwhelm the CPU(s) and have a plethora of pending PHP-FPM operations.

In the screenshot above this server is pm = stable And pm.max_children = 100 Which uses a maximum of about 10GB out of the 32GB installed. Note the highlighted column, self-explanatory. During that screenshot, there were about 200 ‘active users’ (past 60 seconds) in Google Analytics. At that stage, about 70% of the PHP-FPM children are still inactive. This means that PHP-FPM is always set to the maximum capacity of your server’s resources, regardless of the current traffic. Idle processes stay online waiting for traffic spikes and respond quickly instead of waiting time Creating children and then giving them x . kill after pm.process_idle_timeout ends. near me pm.max_requests Set extremely high as this is a production server with no PHP memory leaks. you can use pm.max_requests = 0 With static if you have 110% confidence in your current and future PHP scripts. However, restarting the script over time is recommended. Set the # of requests to a higher number as the point is to avoid the PM overhead. So for example at least pm.max_requests = 1000 …depends on your #K pm.max_children and # requests per second.

Screenshot uses Linux top filtered by the ‘u’ (user) option and the name of the PHP-FPM user. The number of processes displayed is just the ‘top’ 50 or so (not counting), but basically the top displays stats that fit in your terminal window. In this case sorted by %CPU. To see all 100 PHP-FPM processes you can use something like this:

top -bn1 | grep php-fpm

When to use pm ‘ondemand’ and ‘dynamic’

use the afternoon dynamic You may have seen errors like this:

WARNING: [pool xxxx] seems busy (you may need to increase pm.start_servers, or pm.min/max_spare_servers), spawning 32 children, there are 4 idle, and 59 total children

You can try to increase/adjust the setting and still see the same error Describes in this serverfault post , In that case, pm.min was very low and because web traffic fluctuates a lot using pm, with fluctuations and spikes. dynamic It can be difficult to tune correctly. Common advice is that pm . use on demand, As advised in this support thread, However, it’s even worse, because on demand Shutting down idle processes below 0 when there is little or no traffic and then you will end up with traffic fluctuations as well as overhead issues. Unless, of course, you set the idle timeout too high. In which case you should just use pm stable + a high pm max_requests.

However, PM dynamic and especially on demand Can save you when you have more than one PHP-FPM pool. For example, hosting multiple cPanel accounts or multiple websites under different pools. I have for example a server with 100+ cpanel accounts and about 200+ domains and it would be impossible for pm.static or even dynamic to perform well. In college on demand performs well as more than two thirds of websites receive little or no traffic and with on demand This means all the kids will stop saving tons of server memory! Thankfully, cPanel developers figured it out and now it’s default on demand. Pagain with dynamic By default, this did not make PHP-FPM an option on busy shared servers. many people will use suphp due noon dynamic The inactive cPanel PHP-FPM is eating up memory on the pool/accounts as well. Chances are, if you get good traffic, you won’t be hosted on a server with a lot of PHP-FPM pools (shared hosting).


When it comes to PHP-FPM, once you start delivering serious traffic, on demand, And dynamic Process managers for PHP-FPM can limit throughput due to inherent overhead. Know your system and set up your PHP-FPM processes to match your server’s maximum capacity. start with pm.max_children pm. set based on maximum usage of dynamic either on demand And then increase to the point where the memory and CPU can process without being overwhelmed. you will see that with pm stableBecause you keep everything in memory, over time traffic spikes will cause fewer spikes in CPU and your server’s load and CPU averaging will become easier. Average size of your PHP-FPM process will vary per web server requiring manual tuning, thus why more automated overhead process manager dynamic And on demand – There are more popular recommendations. I hope this was a useful article.

update: couple far Benchmark comparison graph. Keeping PHP-FPM processes in memory helps performance at the cost of increased memory usage by letting them sit waiting. Find your setup sweet-spot.

PHP-FPM PM Comparison

Originally Published: 10 October 2017

Leave a Comment