PHP-FPM: How to Calculate pm.max_children Correctly

What is pm.max_children?

This is the maximum number of simultaneous PHP processes that the pool can execute.

Each process = 1 active PHP request. Each process consumes RAM.

👉 If the limit is exceeded → error 502 / timeout
👉 If it gets excessive → swap / OOM / slow server


1️⃣ Main rule (actual formula)

pm.max_children = RAM available for PHP
                  ÷
                  average resource consumption of a 1 PHP process

Simple, but you need to measure it correctly.


2️⃣ Find out how much RAM is available to PHP.

Step 1 – Total RAM

free -m

Example:

Total: 12288 MB

Step 2 – Reserve RAM for the system

Always book:

  • OS + services: 2–3 GB
  • MySQL/MariaDB: 30–40% of RAM
  • Cache (Redis, OPcache): 500 MB – 1 GB

Real-life example (12 GB RAM):

Total:        12288 MB
System:       2048 MB
MariaDB:       4096 MB
Cache/Others:   512 MB
-------------------------
Available PHP: ~5632 MB

3️⃣ Measure the actual power consumption of a PHP-FPM process.

Correct method (production)

ps --no-headers -o "rss,cmd" -C php-fpm | awk '{sum+=$1} END {print sum/NR/1024 " MB"}'

Example output:

42 MB

📌 In WordPress:

  • PHP simple: 30–40 MB
  • WooCommerce: 50–80 MB
  • Sites heavy: 100+ MB

4️⃣ Calculate the pm.max_children

Using the example:

5632 MB ÷ 42 MB ≈ 134 processes

Safe value:

pm.max_children = 120

📌 Always leave a 10–15% margin.


5️⃣ Choose the correct PM (this changes everything)

pm = ondemand
pm.max_children = 120
pm.process_idle_timeout = 10s

✔ Less RAM
✔ Ideal for WordPress
✔ Prevents idle processes


🔹 dynamic

pm = dynamic
pm.max_children = 120
pm.start_servers = 10
pm.min_spare_servers = 5
pm.max_spare_servers = 20

⚠️ It uses more RAM (always-on processes).


6️⃣ Environments with CloudLinux (LVE)

👉 The calculation should be per account, not global.

Example per user:

  • LVE RAM: 1 GB
  • PHP Process: 40 MB
1024 ÷ 40 ≈ 25
pm.max_children = 20

📌 This prevents a website from crashing the server.


7️⃣ Signs of a misconfigured pm.max_children error.

Very low

  • Errors 502
  • server reached pm.max_children
  • Slowness under load

Very high

  • Swap active
  • OOM Killer
  • Server slow even with no traffic

8️⃣ Real-time monitoring

watch -n1 "ps -ylC php-fpm --sort:rss | head"

View errors:

journalctl -u php-fpm

9️⃣ Exemplo final (produção WordPress)

Server:

  • 12 GB RAM
  • MariaDB 11.x
  • CloudLinux
  • Nginx + Apache
pm = ondemand
pm.max_children = 120
pm.process_idle_timeout = 10s
pm.max_requests = 500

✅ Quick checklist

✔ RAM measured correctly
✔ Actual PHP usage calculated
✔ Safety margin applied
✔ pm=ondemand used
✔ Active monitoring