Skip to content
EdgeServers
Blog

PHP-FPM pool tuning in production — the static vs dynamic vs ondemand decision

May 12, 2026 · 1 min read · by Sudhanshu K.

The single most common PHP performance issue on incoming audits: PHP-FPM in dynamic mode with default sizing that was appropriate for a 1GB VPS in 2014, running on a 16GB box, while the application is starving at 5 children. The other common one: pm = ondemand on a high-RPS production site that pays the fork cost on every burst.

This is the pool tuning we apply during onboarding, the slowlog discipline we enforce afterward, and how to know if it's working.

The pool we usually ship

; /etc/php/8.3/fpm/pool.d/www.conf
pm = static
pm.max_children = 50
pm.max_requests = 1000
 
request_terminate_timeout = 60s
request_slowlog_timeout = 5s
slowlog = /var/log/php-fpm/slow.log
 
pm.status_path = /fpm-status
ping.path = /fpm-ping

static once you know the right max_children — no fork cost on bursts, predictable memory. Calculate max_children as (available RAM - OS overhead - other services) / per-process memory. Measure per-process memory under load, not at idle.

The full write-up covers:

  • The pm modes — static vs dynamic vs ondemand, and when each is right
  • Calculating pm.max_children from observed per-process memory under load
  • pm.max_requests and why setting it to 0 (default) is wrong
  • Slowlog tuning — the 5-second threshold and the patterns it surfaces
  • The /fpm-status Nginx wiring and what each metric means
  • Coordinating PHP-FPM tuning with the OPcache + JIT config on the same host

We ship this configuration on every managed PHP stack.

Full article available

Read the full article