Scaling PHP in 2009: Why You Should Ditch mod_php for PHP-FPM and Nginx
If you are still serving PHP applications using Apache's standard mod_php handler in a high-traffic environment, you are essentially driving a tractor on the E6 motorway. It works, but it’s heavy, slow, and blocks traffic.
I recently audited a large e-commerce setup in Oslo running on a standard LAMP stack. Their server—a respectable Dual Xeon with 8GB RAM—was crashing every day at 18:00 when traffic peaked. The cause? Apache processes were consuming 40-50MB each. When you have 200 concurrent users, that math simply doesn't work. The server hit swap, disk I/O skyrocketed, and the load average hit 50.0.
The solution isn't just "buying more RAM." It's changing architecture. It is time to separate the web server from the PHP interpreter using PHP-FPM (FastCGI Process Manager).
The Problem with Apache and mod_php
Apache with the Prefork MPM embeds the PHP interpreter into every single worker process. This means that even if a user is downloading a 5KB style.css or a logo.jpg, your server is spawning a heavy process with a full PHP engine loaded in memory. It is a massive waste of resources.
Furthermore, under heavy load, the MaxClients directive in Apache becomes a hard ceiling. Once reached, new connections queue up and eventually time out.
Enter Nginx and PHP-FPM
The new contender, Nginx (engine-x), handles static files asynchronously with a tiny memory footprint. It doesn't embed PHP. Instead, it acts as a reverse proxy, passing dynamic requests to a backend PHP processor.
Until recently, managing FastCGI processes was a nightmare involving spawn-fcgi and messy init scripts. PHP-FPM changes this. It is a patch for PHP that provides robust process management, adaptive process spawning, and graceful restarts without losing connections. While it is not yet merged into the PHP core (we are hoping for inclusion in PHP 5.3.3 next year), it is stable enough for production use right now.
Step 1: The Architecture
We will use Nginx on port 80 to serve images, CSS, and JS directly from disk. It will proxy .php requests to PHP-FPM running on 127.0.0.1:9000.
Step 2: Installing PHP-FPM on CentOS 5
Since FPM is a patch, you often need to compile PHP from source or use a third-party repository like Remi or UtterRAM. If you are building from source (recommended for full control), the configure command looks like this:
./configure \
--enable-fastcgi \
--enable-fpm \
--with-mcrypt \
--with-zlib \
--enable-mbstring \
--with-openssl \
--with-mysql \
--with-mysql-sock=/var/lib/mysql/mysql.sock \
--with-gd
Step 3: Configuring php-fpm.conf
This is where the magic happens. The XML configuration file allows you to define "pools" of workers. For a server with 4GB of RAM reserved for PHP, you might use static sizing to avoid the overhead of spawning:
static
100
30s
1024
Pro Tip: Use request_terminate_timeout to kill scripts that hang. In standard mod_php, a script stuck in an infinite loop can keep an Apache slot occupied indefinitely. FPM acts as a ruthless supervisor, killing the worker and freeing resources.
Step 4: Nginx Configuration
In your nginx.conf server block, we tell Nginx to talk to the FPM daemon:
server {
listen 80;
server_name example.no;
root /var/www/html;
# Serve static files directly
location ~* \.(jpg|jpeg|gif|png|css|js|ico|xml)$ {
access_log off;
expires 30d;
}
# Pass PHP scripts to FastCGI server
location ~ \.php$ {
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME /var/www/html$fastcgi_script_name;
include fastcgi_params;
}
}
The Hardware Reality: Why Virtualization Matters
Software optimization can only go so far. If your underlying storage subsystem is slow, your database (MySQL) will bottleneck everything. This is particularly relevant here in Norway, where data sovereignty and the Personopplysningsloven (Personal Data Act) compel us to host locally rather than on cheap, oversold servers in the US.
Many budget VPS providers use OpenVZ (container-based). In OpenVZ, you share the kernel with hundreds of other "noisy neighbors." If they thrash the disk, your site slows down. Furthermore, memory limits in OpenVZ (failcnt) are often "burstable," meaning they aren't guaranteed.
At CoolVDS, we rely strictly on Xen HVM virtualization. This provides true hardware isolation. When you provision a CoolVDS instance, you get:
- Dedicated Kernel: You can tune
sysctl.confTCP stack settings without permission denied errors. - Guaranteed RAM: No overselling. If you buy 2GB, you get 2GB.
- High-Performance Storage: We utilize Enterprise 15k RPM SAS drives in RAID-10 arrays. This drastically reduces I/O wait times compared to standard SATA drives found in budget hosting.
Latency Checks (Oslo to Europe)
| Source | Destination | Avg Latency |
|---|---|---|
| CoolVDS (Oslo) | NIX (Norwegian Internet Exchange) | < 2ms |
| CoolVDS (Oslo) | Frankfurt | ~25ms |
| Budget Host (US East) | Oslo User | ~110ms |
For a PHP application performing multiple database queries per page load, disk latency and network latency add up. Saving 20ms on the network and 5ms on disk I/O per query results in a site that feels "instant" to the end user.
Conclusion
The days of relying on the default Apache installation are ending for serious web properties. The combination of Nginx's event-driven architecture and PHP-FPM's robust process management allows you to serve 3x to 5x more traffic on the exact same hardware.
However, running this stack requires a stable, isolated environment where you have root access to compile patches and tune the kernel. Don't let IOwait kill your SEO rankings.
Ready to compile your own stack? Deploy a Xen-based instance on CoolVDS today and get full root access in under 60 seconds.