
mod_php (also written as mod_php5 or mod_php7 depending on the PHP version) is an Apache module that embeds the PHP interpreter directly into every Apache worker process. When a request hits an Apache server configured with mod_php, the PHP engine is already loaded in memory inside the same process that handles HTTP connections. There is no separate process to spawn, no socket to connect to — PHP executes inline.
This architecture made a lot of sense in the early 2000s when shared hosting was king and servers ran the Apache prefork MPM. With prefork, every concurrent HTTP request gets its own forked child process. Because PHP is baked into each process, there is zero overhead from inter-process communication. For low-traffic sites handling a few dozen simultaneous visitors, this model works well enough and is simple to configure.
The downside becomes obvious under load. Every Apache prefork child — even one that is serving a static CSS file or waiting on a slow client download — carries the full PHP interpreter in memory. On a server with 200 MB of RAM allocated to PHP, running 50 Apache workers means 10 GB of RAM just for PHP processes that may not even be executing PHP at any given moment. This is fundamentally wasteful and it is the primary reason mod_php fell out of favour for serious production deployments.
PHP-FPM stands for FastCGI Process Manager. Rather than embedding PHP inside the web server, PHP-FPM runs as a completely separate service — a pool of PHP worker processes that the web server communicates with over a Unix domain socket or a TCP socket using the FastCGI protocol. This separation is the architectural shift that changes everything.
When Nginx (or Apache with mod_proxy_fcgi) receives a request for a PHP file, it passes the request to PHP-FPM via the socket, waits for the response, and returns it to the client. The web server itself never loads PHP. This means Nginx workers stay lean and can handle thousands of concurrent connections with minimal memory, while the PHP-FPM pool handles only what it needs to execute PHP code.
PHP-FPM ships with three process manager modes that control how worker processes are managed:
PHP-FPM also supports multiple pools, meaning you can run different PHP versions simultaneously and assign each site to its own pool with independent resource limits — something that is impossible with mod_php.
Raw throughput benchmarks comparing mod_php and PHP-FPM on equivalent hardware consistently show PHP-FPM delivering 20–40% more requests per second on workloads heavier than a handful of concurrent users. The gap widens significantly under high concurrency because of how each architecture handles memory pressure.
Consider a typical WordPress site benchmark run with Apache Bench (ab) at 100 concurrent connections:
The memory story is the critical one. With mod_php under Apache prefork, every worker process holds a full copy of the PHP interpreter. Under PHP-FPM, the web server workers are tiny — an Nginx worker typically uses 2–5 MB — and only the PHP-FPM processes themselves carry the interpreter overhead. This allows the operating system to handle far more concurrent connections before running out of memory.
If you are running WordPress on Apache with mod_php and your server regularly hits memory limits, switching to Nginx + PHP-FPM is often the single highest-impact change you can make. Many users report cutting memory usage by 60–70% with no application code changes required.
Response time under load is also meaningfully better with PHP-FPM. Because Nginx can queue requests and pass them to available PHP-FPM workers, the server degrades gracefully — requests wait briefly in the queue rather than triggering new process forks that exhaust RAM. With mod_php under prefork, running out of available workers tends to produce dramatic latency spikes or connection refusals.
Security is another area where PHP-FPM has a clear structural advantage. With mod_php, all virtual hosts on the server share the same PHP process and run under the same system user as Apache (typically www-data). This means a PHP script belonging to one site can theoretically read files from another site on the same server — a serious concern on any multi-tenant setup.
PHP-FPM solves this with per-pool user configuration. Each site gets its own pool that runs under a dedicated system user. A compromised script on site A runs as site_a_user and cannot read files owned by site_b_user. This is the same isolation model used by CloudStick when provisioning PHP environments — each website runs in its own PHP-FPM pool with a unique system user, providing genuine file-system-level separation without needing chroot jails or containers.
Per-site PHP configuration is another practical advantage. With mod_php, there is one global php.ini and per-directory overrides via .htaccess are limited in scope. With PHP-FPM, each pool has its own php.ini settings via php_admin_value and php_value directives, and each pool can be pinned to a completely different PHP version. Running PHP 8.1 for a legacy app and PHP 8.3 for a new application on the same server simultaneously is trivial.
There is also an operational benefit: restarting a PHP-FPM pool for one site does not affect any other site on the server. With mod_php, a full Apache restart is required to reload PHP configuration changes, briefly interrupting all hosted sites.
Migrating from mod_php to PHP-FPM on a Ubuntu 22.04 server running Apache takes less than ten minutes. The steps below assume PHP 8.2, but the process is identical for any version available in the ondrej/php PPA.
After enabling php8.2-fpm, Apache routes all *.php requests through the FastCGI socket at /run/php/php8.2-fpm.sock. The PHP-FPM pool configuration lives in /etc/php/8.2/fpm/pool.d/www.conf — this is where you tune the process manager, set the pool user, and adjust per-pool php.ini values.
If you are using Nginx instead of Apache, the equivalent approach is to configure a fastcgi_pass directive in your server block pointing at the PHP-FPM socket, and include fastcgi_params along with the standard FastCGI parameters. Nginx does not support mod_php at all, so if you are on Nginx you are already using PHP-FPM (or a CGI variant), whether you realise it or not.
For the vast majority of use cases in 2026, PHP-FPM is the correct choice. The performance advantage, memory efficiency, per-site isolation, and operational flexibility make it the clear winner for any server running more than a handful of low-traffic sites or serving any meaningful concurrent user load.
There are narrow scenarios where mod_php remains defensible:
.htaccess with mod_php. In practice, this limitation rarely blocks migration since PHP-FPM pool-level configuration covers almost every legitimate use case.The performance gap is also not uniform across all request types. For pure PHP workloads — pages with heavy computation, database queries, and no static assets — the per-request overhead difference between mod_php and PHP-FPM is small (a few milliseconds of FastCGI socket overhead). The real advantage of PHP-FPM shows up in memory consumption and in the ability to serve many more concurrent requests before the server becomes resource-constrained.
Do not disable mod_php without first confirming that PHP-FPM is running and that Apache has been reloaded. If the transition is incomplete, Apache will return raw PHP source code to browsers rather than executing it — a serious security exposure if the PHP files contain credentials or API keys.
If you are evaluating the right PHP handler for a new server or migrating an existing stack, the recommendation is unambiguous: use PHP-FPM with Nginx, or use PHP-FPM with Apache via mod_proxy_fcgi. The migration is low-risk, reversible, and in most real-world scenarios produces measurable improvements in throughput and memory usage within minutes of deployment.
mod_php had its era, and it served the web well during the Apache-centric hosting boom. But the architecture carries fundamental constraints that cannot be engineered away — the PHP interpreter will always consume memory in every web server worker, regardless of whether that worker is serving PHP. PHP-FPM cleanly separates those concerns, and the performance and operational benefits speak for themselves on any server that matters.

