Tuning PHP-FPM in cPanel: Balancing Worker Persistence Against RAM Limits
PHP-FPM in cPanel speeds up PHP execution, but persistent workers consume RAM even when idle. Learn how to size pm.max_children per domain without triggering the OOM killer.
06 Mar 2026, 00:02 UTC

The Problem: Faster PHP, Slower Server
You switch a domain to PHP-FPM in cPanel's MultiPHP Manager because it promises better performance. A day later, the server starts killing processes or swapping heavily. The culprit is rarely PHP-FPM itself. It is treating a per-domain concurrency limit as a global speed switch.
The useful takeaway: PHP-FPM improves throughput by keeping PHP workers alive between requests, but those workers hold memory even when idle. The engineering decision is whether each domain's pool fits inside your server's total RAM budget.
How PHP-FPM Differs From Older Handlers
Older handlers like suPHP or DSO (mod_php) either spawn a fresh interpreter for every request or share a single interpreter across all sites. PHP-FPM takes a middle path: it runs a pool of persistent worker processes under each domain's user account.
Because the workers persist, they skip the startup cost that CGI-style handlers pay on every request. Because they run as the domain user, filesystem isolation remains intact—one site cannot read another's files through PHP. The trade-off is that a pool is always resident in memory, even when no one is visiting the site.
The One Parameter That Matters Most
cPanel's MultiPHP Manager exposes the pool setting pm.max_children directly. This value caps the number of simultaneous PHP workers a single domain may run. It is the primary lever for balancing memory use against traffic spikes.
If your average PHP request consumes roughly 50 MB of RAM, a pool with pm.max_children=10 can claim 500 MB for that domain alone. Multiply that across dozens of low-traffic domains and you can exhaust server memory long before any real traffic arrives.
Worked Example: Sizing a Pool for a Shared Server
Assume a server with 8 GB of RAM hosting 15 cPanel accounts. You want PHP-FPM to use no more than about 40 percent of total RAM, leaving headroom for MySQL, Apache, and the OS. That gives you roughly 3.2 GB for all PHP pools combined, or about 213 MB per domain.
Before changing anything, measure a single PHP worker's memory footprint. As root over SSH or in WHM's Terminal, run:
ps -o rss=,cmd -C php-fpm | grep example_user
Replace example_user with the actual cPanel username. The rss column reports resident memory in kilobytes. If a typical worker shows around 60,000 KB (about 60 MB), then a conservative pm.max_children for this server is 3 or 4, not 10 or 20.
Set that value in MultiPHP Manager for the domain. The interface writes it to the user's pool definition, and cPanel preserves that setting across updates. Hand-editing files under /opt/cpanel/ea-phpXX/root/etc/php-fpm.d/ risks being overwritten by EasyApache 4 rebuilds.
Trade-offs and Limitations
PHP-FPM is not free. Idle workers still consume memory, so enabling it across many low-traffic domains can trigger the Linux OOM killer. If the server starts terminating processes under load, the pool sizes—not the handler choice—are the first thing to review.
Switching handlers briefly disrupts PHP execution while Apache and the PHP-FPM service restart. Exact menu labels, available handlers, and default pool values also vary by cPanel and EasyApache 4 version, so confirm the current interface before assuming a setting name.
How to Verify and Roll Back
After enabling PHP-FPM, create a phpinfo() page in the domain's document root and load it in a browser. Confirm the Server API line reports FPM/FastCGI and that the selected PHP version is active.
To inspect the generated pool file, run as root:
cat /opt/cpanel/ea-php82/root/etc/php-fpm.d/example.com.conf
Replace ea-php82 with your installed PHP version and example.com.conf with the domain's pool file. Check that the user, group, and pm.max_children values match what you set in the interface.
If memory pressure appears, the rollback is straightforward: return to MultiPHP Manager and select the previous handler for that domain. The change is stateful, so expect another brief restart while the old handler takes over.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.