PHP-FPM Pool Calculator for Server Sizing

July 10, 2026

PHP-FPM Pool Calculator

Estimate max children, spare server limits, memory headroom, CPU fit, throughput pressure, and database connection safety for a PHP-FPM pool.

⚙Named PHP-FPM Presets

📈Pool Inputs

Controls how the calculator frames the final pool directives.
Adjusts the soft CPU concurrency check.
Memory set aside for this pool after OS, web server, database, and cache.
Use measured resident memory per PHP-FPM child, not only PHP memory_limit.
Covers OPcache, realpath cache, shared extensions, allocator variance, and pool overhead.
Subtracted before dividing memory into children.
Use the cores or vCPU share realistically available to the PHP pool.
End-to-end PHP time after web server handoff, including DB and remote waits.
Peak requests actively needing PHP workers, not static file traffic.
Used with request duration to check throughput worker demand.
Maximum safe DB connections after reserving slots for admin, replicas, jobs, or other apps.
Limits max children when every worker can hold a DB slot.
Initial warm children for dynamic mode.
Minimum idle workers kept ready for traffic bursts.
Maximum idle workers before PHP-FPM trims the pool.
How long an ondemand child can sit idle before it exits.

Recommended Pool Sizing

Recommended max children
0
workers
Memory limited ceiling
0
workers by RSS
Estimated throughput
0
PHP req/sec at average duration
Pool RAM at cap
0 MB
including reserve
Primary limiting factor-
Usable RAM after reserve and headroom-
CPU soft fit for selected workload-
Workers needed for concurrency and RPS-
Database cap translated to children-
Suggested pool directives-
Spare server check-

🗂PHP-FPM Sizing Reference Grid

RSS
Resident memory per child is the main RAM input
OPcache
Shared memory reserve is not multiplied per child
CPU
Workers above CPU fit can queue under CPU-heavy load
DB
Max children can exhaust MySQL or PostgreSQL slots

📋Process Manager Comparison

static

Runs exactly the configured number of children all the time.

  • Predictable latency
  • Highest idle memory use
  • Good for steady traffic

dynamic

Keeps warm spare children and scales between idle and max.

  • Best default for most sites
  • Requires spare tuning
  • Good for mixed traffic

ondemand

Starts children only when requests arrive, then removes idle ones.

  • Lowest idle memory
  • Cold-start tradeoff
  • Good for quiet apps

📚Reference Tables

Application type Common child RSS Reserve pattern Pool note
Small WordPress 48 to 96 MB 128 to 256 MB OPcache Plugins decide the real number
WooCommerce or Drupal 96 to 220 MB 256 to 512 MB OPcache DB cap often matters
Laravel API 70 to 160 MB 128 to 384 MB shared CPU profile varies by endpoint
Nextcloud or media app 120 to 300 MB 256 to 768 MB reserve Uploads and previews spike RSS
RAM budget Child RSS 64 MB Child RSS 128 MB Child RSS 256 MB
1 GB PHP budget 12 to 14 children 6 to 7 children 3 children
2 GB PHP budget 26 to 29 children 13 to 14 children 6 to 7 children
4 GB PHP budget 55 to 59 children 27 to 29 children 13 to 14 children
8 GB PHP budget 112 to 118 children 56 to 59 children 28 to 29 children
Directive static dynamic ondemand
pm.max_children Total fixed workers Maximum burst workers Maximum spawned workers
pm.start_servers Ignored Initial warm pool Ignored
pm.min_spare_servers Ignored Lowest idle warm pool Ignored
pm.max_spare_servers Ignored Highest idle warm pool Ignored
pm.process_idle_timeout Ignored Ignored Idle child lifetime
Scenario Typical mode Primary constraint Watch first
Small VPS blog ondemand or dynamic RAM Swap and slow log
Store checkout dynamic DB connections Queue length and DB waits
Internal API static or dynamic CPU and latency p95 duration
Multi-app hosting dynamic per pool Aggregate RAM Total children across pools

💡Pool Sizing Tips

Measure real workers: sample ps -o rss or process monitoring during representative traffic. PHP memory_limit is a ceiling, while RSS is what the operating system actually has to keep resident.
Keep DB slots boring: leave connection room for migrations, cron jobs, CLI tasks, replicas, monitoring, and another pool. A web pool that consumes every DB slot can make recovery harder.
This calculator provides a starting point for one PHP-FPM pool. Recheck after deploying with slow logs, max children reached messages, process RSS, swap activity, database connection counts, and upstream response time.

The site loads perfectly well. But as soon as someone tries to checkout, the spinner comes up, and stays on long enough to feel unsafe. And then the connection just times out. That’s not normaly a code problem. More often than not, it’s that you’ve got a pool of PHP workers that just run out of hands to shake when traffic really hits. Getting size of your PHP-FPM pool right isn’t about pure horsepower; it’s about managing how much resources you use so that there are no bottleneck when traffic hit.

For most folks, this means guessing their max_children limit by looking at server’s total RAM and dividing it by some arbitrary number. This doesn’t work, because it doesn’t take into account what your child processes actualy use in memory, the database connections, or the operating system itself. That’s where the calculator comes in (above). Plug your own constraints into the calculator, and let it do the math for you, no need for guesswork about CPU vs. These is memory bottlenecks.

How to Fix Your PHP Server Settings

Newcomers are often confused by one thing: what is “average child RSS“? Here’s how the memory_limit setting in your php.ini file won’t tell you the whole story: It ignores the Zend engine overhead, shared libraries, allocator variance, etc. These isn’t within the PHP memory_limit range, yet they still count as part of the resident set size. Measure real-world RSS with a tool like ps when your application is under normal load, and you’ll arrive at more conservative denominator for your calculation. Underestimate here, and you’ll have too many children, trigger swapping and watch your site crawl to a halt under what should of be moderate traffic.

The other side of the coin are not just about workers, but also memory reserves. Because OPcache requires some shared memory, and the OS wants some breathing room, you can’t just stuff every megabyte full of PHP processes. To avoid this, the calculator requests an additional reserve block for those shared elements. That way, you don’t end up double counting any memory, since that memory is only allocated once regardless of how many workers you’re running. A little thing in your config file, but get it wrong and you’ll have a mess of fragmentation and slow starts. You want enough headroom that if things suddenly pick up then the kernel won’t need to start paging out data to disk. Paging is where performance goes to die.

And then there’s the database connection limit. Each PHP worker typically maintains a single connection to MySQL or PostgreSQL. And if your number of DB slots isn’t enough for your max_children, you’ll exhaust your connections long before exhausting memory. The tool translates those database caps into an actual hard ceiling on your pool size. That way, your web server never commits to handling more concurrent requests then it can actually handle in its backend. It establishes a predictable failure mode: instead of a completely locked-up application, it’s just an application that stays responsive.

Depending on traffic patterns, one of these two process manager modes will make more sense different than the other. If traffic is highly variable, static pools waste resources while dynamic pools maintains a pool of warm spares to handle bursts (usually the sweet spot for most apps). For memory-intensive apps, on-demand modes conserve memory by shutting down idle worker, but you pay a cold-start penalty when they’re needed. The page has a set of reference tables laying it all out for various kinds of applications (an API node behaves differently than a WordPress site). Making the wrong decision will mean wasting memory or adding delay to your users’ experience.

To conclude. Tuning is something that’s iterative. Set some starting values, use these formulas to remove the guesswork, push those out, and monitor the logs. Are any queue filling up? Do you have processes running out of steam? If your system spikes when there are small surges of users, adjust your spare servers. If you’re getting db connection errors, reduce number of max children. You must balance having enough resources without having so many that they makes the system unstable. Measure your reserved memory & RSS and get your baseline correct so you don’t have to guess as much while scaling. Instead of your site fighting in the background, it will be able to handle traffic gracefully. The feeling that it won’t come crashing down is worth the trouble of measuring twice before configuring once.

PHP-FPM Pool Calculator for Server Sizing

Related posts

Leave a Comment