Console Login

Scaling PHP in 2009: Why You Should Ditch mod_php for PHP-FPM and Nginx

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.conf TCP 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.