PHP-FPM Pool Calculator
Size a PHP-FPM pool from available memory and request characteristics, choose between static, dynamic and ondemand process managers, and generate the pool configuration.
Last reviewed by the Radiatus Cloud team
Want this automated for your stack?
We build CI/CD, Kubernetes & IaC pipelines that scale.
Workers are bounded by memory, not by ambition
Each PHP-FPM child is a full process holding its own copy of the interpreter, the loaded extensions and whatever the request allocates. Setting max_children higher than memory allows does not produce more throughput; it produces swapping and then the kernel OOM killer terminating processes at random, which usually takes the database connection pool or the web server with it. The correct figure is available memory divided by the real average child size, and the second number is the one people guess wrong.
Measure the child size rather than assuming it
The memory_limit setting is a ceiling per request, not a typical figure. A WordPress site with a 256 megabyte limit usually has children resident at 40 to 80 megabytes. Reading the actual resident size from ps, and using the average rather than the peak, gives a max_children several times higher than sizing from memory_limit would, which is the difference between a server that handles its load and one that queues.
Choosing a process manager
Static keeps a fixed number of children alive and gives the most predictable latency, at the cost of holding all that memory permanently. Dynamic scales between a minimum and a maximum and is the sensible default for a general purpose server. Ondemand starts children only when a request arrives and lets them idle out, which suits a server hosting many low traffic sites where most pools would otherwise sit idle holding memory. The wrong choice mostly shows up as either wasted memory or a latency spike while children fork.
Related tools
- CI/CD Security Gap Analyzer — Checklist based analyzer for CI/CD pipeline security gaps.
- Docker Security Scanner — A new tool extracted from the codebase.
- Terraform Scanner — A new tool extracted from the codebase.
- SQL Formatter — Format and indent SQL queries for readability. Handles joins, subqueries and CTEs, supports common dialects, and runs entirely in your browser.
Frequently Asked Questions
How do I find the real memory per child?
Measure it under load: ps --no-headers -o rss -C php-fpm gives the resident size of each child in kilobytes. Take the average rather than the peak, and take it while the site is busy rather than idle.
Should I use static, dynamic or ondemand?
Dynamic for a general purpose server. Static when the traffic is steady and you want the most predictable latency and no fork cost. Ondemand when hosting many low traffic sites, so idle pools release their memory instead of holding it.
What does pm.max_requests do?
It recycles a child after that many requests, which contains memory leaks in the application or in an extension. Between 500 and 1000 is typical. Setting it to 0 disables recycling, which is fine only if you are confident nothing leaks.
Why do I see 502 errors under load?
Usually all children are busy and the listen backlog has filled, so the web server gets a connection refusal. Check the pool status page for a non zero max children reached counter and a growing listen queue before adding workers, since the real cause is often slow requests rather than too few workers.
How does OPcache affect sizing?
OPcache is shared memory outside the per child allocation, so it is counted once for the pool rather than per worker. Reserve it separately from the per child budget, and make sure opcache.memory_consumption is large enough that the cache is not thrashing.
Privacy & Security
Everything runs in your browser; nothing is uploaded.
How to Use
Enter server memory and average request memory and duration to size the worker pool.
Disclaimer: This tool is provided "as is" without warranty of any kind. Results are for educational and utility purposes.