Panellicense

PHP handlers in Plesk: FPM by nginx, FPM by Apache, FastCGI, and CGI

Plesk gives you five PHP handlers per domain — and the choice between nginx-only FPM and Apache-fronted FPM is the one most admins get wrong. Here is the trade-off, with memory math and recommendations.

9 min readUpdated 2026-05-18plesk · php-fpm · nginx · apache
schema: Articleschema: FAQPageschema: BreadcrumbList

The PHP handler dropdown in Plesk has more entries than cPanel's, and the two that matter most — FPM application served by nginx and FPM application served by Apache — look almost identical in the UI. They are not. One is roughly twice as fast on the request hot path and breaks every WordPress site that ships an .htaccess. The other is the safe default and the reason most Plesk hosts cap out at lower req/s than they should.

This is what each handler actually does on a Plesk Obsidian box, what it costs in RAM, where it breaks, and which one to pick by workload. Everything below assumes you are running the Plesk PHP packages (plesk-php83, plesk-php82, etc.) — not a hand-rolled remi or sury install, which Plesk will refuse to manage from the UI.

At a glance

HandlerMemory per idle siteFirst-request latency.htaccess worksFile ownershipBest for
FPM by nginx~25–50 MB~10–30 msNoSubscription userLaravel, Symfony, static-heavy sites, API backends
FPM by Apache~25–50 MB + Apache worker~20–50 msYesSubscription userWordPress, Joomla, Drupal, anything you didn't write
FastCGI (mod_fcgid)~15–30 MB per active site~40–80 msYesSubscription userConstrained boxes where FPM tuning is unrealistic
CGI (mod_cgi + suexec)~0 MB at idle, fork per request~150–400 msYesSubscription userLegacy CGI/Perl-style scripts only
Apache module (mod_php)Shared with Apache prefork~10–20 msYesapache / nobodyNothing — avoid on multi-tenant boxes

The short version: FPM by Apache is the right default for any subscription you didn't write. Switch to FPM by nginx when the application has its own routing layer and you control its config. Treat the other three as legacy or transitional.

FPM application served by nginx

This is the "pure" path. Nginx terminates the request and proxies straight to PHP-FPM over a Unix socket. There is no Apache in the chain. The pool config lives at /etc/php-fpm.d/plesk-phpXX-fpm-domain-N.conf on RHEL-family hosts, or /etc/php/X.Y/fpm/pool.d/ on Debian/Ubuntu, and looks like:

[domain123]
listen = /var/www/vhosts/system/example.com/php-fpm.sock
listen.owner = example_com
user = example_com
group = psacln
pm = ondemand
pm.max_children = 5
pm.process_idle_timeout = 60s

The latency win comes from removing Apache: no .htaccess parse, no MPM worker dispatch, no second proxy hop. On a typical WordPress request hot path you save 15–25 ms per request and roughly half the resident memory.

The cost is that nginx does not read .htaccess. Every rewrite rule, deny block, header override, and security plugin's IP allowlist has to be translated into nginx syntax and pasted into Apache & nginx Settings → Additional nginx directives for the domain. WordPress's stock rewrite block becomes:

location / {
  try_files $uri $uri/ /index.php?$args;
}

That is the easy case. A Wordfence or All-in-One Security plugin spraying 80 lines of mod_rewrite and mod_headers rules into .htaccess is the hard case, and the failure mode is silent — the site appears to work, but the WAF and the redirects don't run.

FPM application served by Apache

The default Plesk picks for new subscriptions. The chain is nginx (frontend reverse proxy serving static files) → Apache (httpd) → PHP-FPM via mod_proxy_fcgi. Apache reads .htaccess on every PHP request, which is where the latency cost comes from — but it also means every mod_rewrite, mod_headers, and mod_deny rule your CMS or your plugin emits just works.

For a multi-tenant Plesk box hosting agency sites you didn't build, this is the only defensible default. The combined nginx-static + Apache-dynamic split means you still get nginx's static-file performance for /wp-content/uploads/*.jpg, while PHP requests get the full Apache compatibility surface.

The pool tuning is identical to FPM-by-nginx — same files, same knobs. The Apache layer adds one httpd worker per active request, ~5–15 MB each. On a 4 GB VPS that's the difference between 80 and 120 sustained PHP-serving sites.

FastCGI application (mod_fcgid)

The pre-FPM Plesk default, kept around for compatibility. Each request forks a new PHP process under suexec; Apache reuses the process for a configurable number of subsequent requests via mod_fcgid before killing it. Memory per active site is lower than FPM (~15–30 MB) because there are no warm idle workers, but request latency is higher and the fork rate is brutal under sudden load spikes — exactly the failure mode that drove the shift to FPM.

Pick FastCGI only when:

  • You have hundreds of mostly-idle subscriptions on a memory-constrained box and per-pool FPM tuning would burn admin hours you don't have.
  • You hit a specific PHP extension that misbehaves in long-lived FPM workers (rare; most fixes are upstream now).

Otherwise FPM-by-Apache wins on every axis.

CGI application

mod_cgi with suexec. Forks a fresh PHP process per request, no reuse. Latency is 150–400 ms minimum because of the fork-and-exec on every hit. Use it for one specific case: a subscription running pre-2010 Perl-style CGI scripts that assume each invocation gets a clean process. Otherwise this handler exists to make a comparison table complete.

Apache module (mod_php)

mod_php loads PHP into the Apache worker. Lowest per-request overhead, no fork, no IPC. The catch is that every PHP request runs as the Apache user (apache on RHEL, www-data on Debian) — not the subscription user. That means:

  • Files PHP writes are owned by apache, breaking quota accounting and any user-level ownership check.
  • One vulnerable site can read every other site's files on the same Apache instance.
  • Plesk's PHP Selector (per-domain PHP version) does not work, because mod_php is a single loaded module per Apache.

mod_php was deprecated as the default in Plesk Obsidian and removed from the dropdown for new domains in Obsidian 18.0.55+. If you see it on an old subscription, switch it to FPM-by-Apache and don't look back. There is no shared-hosting case where mod_php is the right answer.

Switching the handler

In the UI: Subscriptions → example.com → PHP Settings → PHP support → PHP version. The handler dropdown is directly below the version picker. Changes apply on save with no downtime — the next request uses the new handler.

From the command line:

plesk bin php_handler --list
plesk bin domain --update -domain example.com -php_handler_id plesk-php83-fpm

Handler IDs follow the pattern plesk-phpXX-{fpm,fpm-apache,fastcgi,cgi,module}. The fpm ID is FPM-by-nginx; fpm-apache is FPM served by Apache. This trips people up — the short name fpm is the more aggressive choice.

Pool tuning that actually matters

For both FPM handlers, the three knobs that decide RAM behavior are the same as on cPanel (see PHP-FPM pool tuning on cPanel for the math — it ports directly):

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

Plesk exposes pm, pm.max_children, pm.max_requests, and a handful of others under PHP Settings → Performance Settings as named fields. Anything else (pm.start_servers, request_terminate_timeout, custom php_admin_value directives) goes into Additional configuration directives at the bottom of the page, which Plesk merges into the pool file on save.

Recommendations by workload

  • WordPress, WooCommerce, Joomla, Drupal, generic CMS hosting: FPM by Apache. The .htaccess compatibility is non-negotiable for sites managed by plugins.
  • Laravel, Symfony, Statamic, custom PHP frameworks with front-controller routing: FPM by nginx. You already write the rewrites, you'll save ~20 ms per request.
  • API backends, headless WordPress, REST/JSON endpoints: FPM by nginx. Latency wins compound at scale.
  • Static-heavy marketing sites with one PHP contact form: FPM by Apache. The handler rarely runs, simplicity wins.
  • Legacy shared box you inherited: FPM by Apache, then audit the slowest 10 subscriptions and consider tuning their FPM pools individually.
  • Anything currently on mod_php: migrate to FPM by Apache. Today.

For multi-tenant hosts running CloudLinux, the answer changes slightly — CloudLinux's PHP Selector replaces Plesk's PHP version handling and adds LVE limits per subscription. That's covered in CloudLinux PHP Selector setup.

What is the difference between FPM served by nginx and FPM served by Apache in Plesk?+
FPM by nginx skips Apache entirely — nginx proxies straight to PHP-FPM, which is faster but means .htaccess files are ignored. FPM by Apache routes PHP requests through Apache so .htaccess works, at the cost of ~15–25 ms and one Apache worker per active request.
Is mod_php still available in Plesk Obsidian?+
It exists on subscriptions created before Plesk Obsidian 18.0.55 but is no longer offered for new domains. Migrate any remaining mod_php domains to FPM by Apache — it has no per-user isolation and breaks the PHP Selector.
Why is my WordPress site broken after switching to FPM by nginx?+
WordPress writes rewrite rules to .htaccess, which nginx does not read. Add the standard WordPress rewrite block to Additional nginx directives under Apache & nginx Settings, and re-add any security-plugin rules manually.
Can I run different PHP handlers for different subscriptions on the same Plesk server?+
Yes. The handler is set per-domain in PHP Settings, and FPM pools are isolated per subscription. Mixing FPM-by-nginx Laravel apps with FPM-by-Apache WordPress sites on the same box is the common pattern.
Which PHP handler uses the least RAM in Plesk?+
FastCGI uses the least at idle because it spawns no warm workers, but it has the highest latency and worst behavior under load spikes. FPM (either flavor) with pm = ondemand is the better RAM/throughput trade-off for almost every host.
How do I switch all subscriptions on a Plesk server to FPM at once?+
Use plesk bin domain --update in a loop over plesk bin domain --list. There is no single global switch — handler is a per-domain setting.

Next steps

Switch in an afternoon

Switch from your current reseller — free.

We migrate active cPanel, Plesk, LiteSpeed and CloudLinux licenses from any reseller. We prorate the first month so you never pay twice, and your customers see zero downtime during the swap.