Static, dynamic, ondemand
Static, dynamic, ondemand
PHP-FPM gives every pool a pm mode, and the mode changes what
pm.max_children means. This page is what fpm-tune writes for each, and the
two cases where it suggests a different mode.
- static: the pool runs exactly
pm.max_childrenworkers, always. The number is the memory the pool commits right now. - dynamic: PHP-FPM keeps a warm floor and scales between it and
pm.max_childrenas load comes and goes, usingpm.start_serversand thepm.min_spare_serverstopm.max_spare_serversband. - ondemand: no workers until a request arrives; each is spawned on demand and killed when idle. The number is a ceiling the pool may reach.
What it writes, per mode
| Mode | Written to zz-fpm-tune.conf |
|---|---|
| static | pm.max_children |
| ondemand | pm.max_children |
| dynamic | pm.max_children, pm.start_servers (25% of it), pm.min_spare_servers (10%), pm.max_spare_servers (50%), each rounded up |
The spare band is re-derived from the new ceiling so PHP-FPM's own scaling stays coherent, and PHP-FPM's ordering rule (min spare, then start, then max spare, then max children, each no larger than the next) is kept. A ceiling of 10 comes out as:
[www-forge]
pm.max_children = 10
pm.start_servers = 3
pm.min_spare_servers = 1
pm.max_spare_servers = 5
Spare settings are written for dynamic pools only. PHP-FPM refuses
pm.start_servers in a static or ondemand pool, and the
sandbox validation would catch that before a
reload, but it is cheaper never to write it.
An ondemand pool seen with no workers teaches the learner nothing about its cost; measuring workers has the rules for what counts.
Why it never changes the mode
The right mode is a trade between idle memory, latency and cold starts, and the
tie-breakers (a latency target, a preference for memory that never moves, forty
pools each hit twice an hour) are not in the numbers on the host. fpm-tune
sizes inside the mode you chose and never writes pm.
| static | dynamic | ondemand | |
|---|---|---|---|
| idle memory | every worker resident, always | scales down to the floor | nothing when quiet |
| latency under load | workers always warm | warm floor absorbs bursts | each burst pays a cold start |
| fits | steady, latency-sensitive, memory to spare | most pools | many pools each rarely hit |
The one suggestion it makes
Two measured shapes get a line under the plan table, and one Mode suggestion
line in the daemon's log the first time each is seen. Neither changes anything.
- A static pool holding idle workers: its busiest moment left at least two workers unused, and they hold at least 256 MiB between them. dynamic or ondemand would hand that memory back between requests, unless you keep them warm for latency on purpose.
- An ondemand pool that is queueing, or that the allocator could not fully satisfy: its bursts are paying cold-start latency, and a dynamic pool's warm floor would absorb them.
It does not push a busy dynamic pool toward static. Telling steady saturation from one spike needs a sustained-load signal it does not keep.
The pm mode is a performance and memory decision and says nothing about
isolating one pool from another; that is user, group, chroot and
open_basedir, and what fpm-tune itself guards is in
the trust boundary.