The PHP handler is the highest-leverage knob on a cPanel server. It decides how much RAM
each account consumes at idle, how fast a cold WordPress request returns, whether files
created by PHP are owned by the user or by nobody, and how the box behaves when a single
account suddenly spikes to 200 concurrent requests.
EasyApache 4 still lists five handlers in the dropdown. In 2026, only two of them are worth running on a shared host, and exactly one is the right answer if you're paying for LiteSpeed. This is the comparison, with the memory math, the failure modes, and the cases where the obvious pick is wrong.
At a glance
| Handler | Memory per idle site | Throughput | File ownership | Status in EA4 | Best for |
|---|---|---|---|---|---|
| PHP-FPM | ~30–60 MB (1 worker pool) | High | User | Default, fully supported | Most cPanel hosts |
| LSAPI (mod_lsapi or LSWS) | ~5–15 MB (shared workers) | Highest | User | Supported, needs LiteSpeed | High-density shared hosting |
| suPHP | ~0 MB at idle, fork per request | Low | User | Removed in EA4 11.96+ | Nothing — don't pick |
| CGI | ~0 MB at idle, fork per request | Lowest | User | Available, rarely correct | Legacy CGI scripts only |
| FCGI (mod_fcgid) | ~20–40 MB per active site | Medium | User | Available, mostly a fallback | Constrained boxes where FPM tuning is unrealistic |
| DSO (mod_php) | Shared with Apache | High | nobody / Apache | Removed | Nothing — gone for good reasons |
If you want the short version: PHP-FPM is the right answer for almost every cPanel server
running on Apache. LSAPI is the right answer if you've already paid for LiteSpeed Web
Server or installed mod_lsapi. Everything else is a historical
footnote or a workaround for a specific constraint.
PHP-FPM
FPM is FastCGI Process Manager. cPanel runs one pool per domain (or per account, if you
enable the account-level setting in MultiPHP Manager), with workers spawned to handle
incoming requests over a Unix socket. Each pool is owned by the cPanel user, so files PHP
writes have the right ownership and chmod semantics work without surprises.
The pool config lives at /opt/cpanel/ea-phpXX/root/etc/php-fpm.d/<user>__<domain>.conf
and the three knobs that matter are:
pm = ondemand
pm.max_children = 10
pm.process_idle_timeout = 10s
pm = ondemand— workers spawn on first request and exit afterprocess_idle_timeout. Low idle memory cost, but the first request after idle pays a 50–200 ms cold-start.pm = dynamic— keeps a configurable number of workers warm. Faster first request, more RAM per site at idle.pm = static— fixed pool size, always warm. Lowest latency, highest memory cost. Worth it only for the busiest few sites on the box.
PHP-FPM is the modern default for two reasons. First, it isolates PHP per user without forking on every request, so throughput on a busy WordPress site is roughly an order of magnitude better than suPHP. Second, OPcache and APCu actually work — the cache persists across requests within a pool, where suPHP's per-request fork throws it away.
The cost is RAM. A pool with pm.max_children = 10 and a 256M memory_limit reserves up
to ~2.5 GB if every worker is busy, and at idle on ondemand still costs the master
process plus any warm workers. On a 200-account shared host this adds up.
LSAPI
LSAPI (LiteSpeed Server API) is a different protocol — not FastCGI — that keeps PHP workers
attached to the web server and handed requests without going through a socket buffer in the
same way. On a LiteSpeed Web Server install, it's the
default and there's nothing to configure. On Apache, you install mod_lsapi (which ships
with cPanel's EA4 repos if you have a CloudLinux or LiteSpeed license that includes it) and
select "lsphp" in MultiPHP Manager.
Three properties make LSAPI the right pick for high-density hosting:
- Lower idle memory. Workers are shared per user, not per domain, and the worker model is leaner than FPM's. A box that runs 250 accounts at 60% RAM under FPM will often run the same load at 35% under LSAPI.
- No
.htaccessreload penalty. LSWS reads.htaccesslive, where Apache+FPM has to reload changes viaapachectl gracefulif you change anything beyond rewrite rules. - Direct integration with LSCache. The cache is in-process; the latency of a cache hit on LiteSpeed+LSAPI is usually under 5 ms, versus 15–30 ms for FPM serving the cache through a redis or file backend.
The trade-off is licensing. LSWS is a paid product; mod_lsapi on Apache also requires a
license (typically bundled with CloudLinux Solo/Admin/Pro or
included with LiteSpeed). For a single VPS the cost is modest; across a 50-server fleet,
it's a real budget line — see the LiteSpeed tier breakdown
for the math.
suPHP, CGI, and mod_fcgid
These three exist for historical reasons. cPanel deprecated suPHP in 2019 and removed it from EA4 in version 11.96 (early 2022). You may still see it referenced in old tutorials — ignore them. The reason: suPHP forks a new PHP process on every single request, which means no OPcache, no APCu, and roughly 20–50 ms of pure overhead per request before PHP runs a single line of user code. A WordPress page that takes 200 ms under FPM takes 350–500 ms under suPHP, and PHP forking on a busy server consumes CPU that should be doing actual work.
mod_fcgid is the FastCGI handler from before PHP-FPM existed. It keeps PHP processes
alive between requests, so OPcache works, but the process management is cruder than FPM's
and the per-site memory footprint is worse. It survives in EA4 mainly as a fallback for
operators who can't get FPM tuning right on a memory-constrained VPS.
CGI (plain CGI, no setuid wrapper) is genuinely the right answer for exactly one case: a
legacy .cgi script that needs to run as a specific user without the security model of
suPHP. If you're not migrating a 2008-era Perl billing system, you don't need it.
Memory math: 200 cPanel accounts, worked example
Assume a 16 GB shared-hosting VPS, 200 active accounts, an average of 1 domain per account,
PHP 8.3, memory_limit = 256M. Headroom for MySQL, Exim, and the OS: 4 GB. That leaves
~12 GB for PHP.
FPM, pm = ondemand, pm.max_children = 10:
- Idle: master process per pool, ~3 MB × 200 = 600 MB
- At peak (10% of sites serving concurrent requests, 3 workers average): 20 sites × 3 workers × 80 MB = 4.8 GB
- Total realistic: ~5.5 GB, fits comfortably
FPM, pm = dynamic, pm.start_servers = 3, pm.max_children = 10:
- Idle: 3 warm workers × 80 MB × 200 = 48 GB
That doesn't fit. dynamic as the default for every account on a 200-site box is the
mistake most operators make once. Use ondemand as the default and reserve dynamic for
sites that genuinely need warm workers.
LSAPI on LSWS, same accounts:
- Per-user worker pool, average 2 workers warm: 200 × 2 × 30 MB = 12 GB
- But LSAPI's worker memory is shared via copy-on-write more aggressively than FPM, so real RSS is typically 60–70% of that — call it 8 GB
This is why high-density shared hosts converge on LiteSpeed. The crossover happens around 80–100 accounts per node; below that, FPM is fine and you save the license cost.
Switching handlers safely
In WHM, the path is Software → MultiPHP Manager. You can switch per-domain or system-wide. Switching the system default rewrites every domain's handler; switching one domain only touches that one.
The non-obvious failures after switching:
- File ownership. If you're moving away from a server that ran DSO (mod_php), some
files may be owned by
nobody. PHP under FPM or LSAPI runs as the user and will refuse to read those files. Fix withchown -R user:user /home/user/public_htmlbefore switching. - Sessions. PHP sessions stored on disk (the default) move with the file ownership
change. Sessions in Redis or Memcached are fine. Sites using
session_save_path()to a weird location may stop working. - OPcache state. Switching handlers clears OPcache. The first request to each page after the switch is slow. Don't switch during peak hours.
.user.inifiles. Both FPM and LSAPI honour.user.ini. suPHP honouredphp.iniin the docroot. If migrating from a suPHP-era setup, audit for strayphp.inifiles in user directories that no longer take effect.
Test on one low-traffic domain first, watch for 502s in /var/log/apache2/error_log or the
LSWS error log, then roll out.
Common mistakes
- Setting
pm = dynamicas the system default. Memory math above. Useondemandby default,dynamicfor specific busy sites. - Tuning
pm.max_childrenwithoutpm.max_requests. PHP-FPM workers accumulate memory over time (especially with WordPress plugins doing weird things). Setpm.max_requests = 500so workers recycle. - Running LSAPI on Apache without
mod_lsapi. "lsphp" in MultiPHP without the module silently falls back to FPM or fails outright depending on EA4 version. - Forgetting CloudLinux PHP Selector. If users are on different PHP versions via PHP Selector, the handler choice still applies but each PHP version has its own pool config. Tune them separately.
- Switching everyone at once. A handler change is a config rewrite for every domain. On a 200-account box this is 200 chances for something user-specific to break. Roll out in batches and watch error logs.
FAQ
Is PHP-FPM faster than LSAPI on cPanel?+
Why did cPanel remove suPHP from EA4?+
Can I use PHP-FPM with LiteSpeed Web Server?+
Does mod_lsapi work without a LiteSpeed license?+
How do I choose between ondemand, dynamic, and static for PHP-FPM?+
Will switching from suPHP to PHP-FPM break my sites?+
Next steps
- If you're running LiteSpeed and want the matching cache layer wired up correctly, see enabling LSCache for WordPress on cPanel
- For per-account PHP version management on top of whichever handler you pick, the CloudLinux PHP Selector setup guide is the next step
- Before tuning FPM pools any deeper, read CloudLinux LVE tuning without angry customers
—
pm.max_childrenand EP limits interact in ways that look like FPM bugs but are LVE faults. If you don't have a LiteSpeed license yet, check the LSWS tiers before you scale past 100 accounts per node