Console Login
Home / Blog / Server Administration / Stop the Swap Death Spiral: migrating to Nginx & PHP-FPM on CentOS
Server Administration 9 views

Stop the Swap Death Spiral: migrating to Nginx & PHP-FPM on CentOS

@

The Apache bloat is killing your throughput

I saw it happen again last Tuesday. A client running a moderate Magento store on a standard LAMP stack got hit with a traffic spike. Nothing massive—just a localized marketing push here in Norway. The result? Load averages climbed to 25.0, the server started swapping to disk, and the site became as responsive as a brick. The culprit wasn't the code; it was the architecture.

If you are still serving static files through Apache while it carries the overhead of the embedded PHP interpreter (mod_php) for every single request, you are wasting memory. It’s 2011. We have better ways to handle concurrency.

The solution isn't adding more RAM—that’s a band-aid. The solution is moving to an event-driven architecture using Nginx and PHP-FPM (FastCGI Process Manager). This setup separates the web server from the PHP processing, drastically lowering the memory footprint per connection.

Why PHP-FPM changes the game

With mod_php, every Apache child process consumes roughly the same amount of RAM, whether it's serving a complex PHP script or a 1KB style.css file. It's inefficient. Nginx acts as a lightweight proxy, handling thousands of static file connections with just a few megabytes of RAM. It only passes the actual PHP requests to the PHP-FPM backend via a Unix socket or TCP.

Since PHP 5.3.3, FPM is now part of the core. It offers features we desperately needed for years:

  • Adaptive process spawning.
  • Advanced logging for slow scripts (finally).
  • Emergency restart in case of accidental opcode cache destruction.

Configuration: Tuning the Pool

Installing it is straightforward on a CoolVDS CentOS 5 instance using the Remi or EPEL repositories. But the default config will still bottleneck you if you don't touch it. The magic happens in /etc/php-fpm.d/www.conf.

Here is the configuration I use for production environments handling bursty traffic:

; /etc/php-fpm.d/www.conf
pm = dynamic
pm.max_children = 50
pm.start_servers = 5
pm.min_spare_servers = 5
pm.max_spare_servers = 35
request_terminate_timeout = 30s

The Breakdown:

  • pm = dynamic: This is crucial. It means we don't keep unused processes in memory, but we can scale up instantly when the request hits.
  • pm.max_children: Calculate this carefully. If your average PHP process takes 30MB and you have a 2GB VPS, don't set this to 100. Leave room for the OS and the database. On a CoolVDS 1024MB plan, a value of 20-30 is usually the sweet spot.
Pro Tip: Don't forget the Opcode Cache. PHP-FPM is fast, but compiling PHP scripts on every request is slow. Install APC (Alternative PHP Cache). Set apc.shm_size=128M in your php.ini. This single change can double your requests per second.

The Nginx Handoff

You need to tell Nginx to pass `.php` files to the FPM daemon. Avoid the "If is evil" rewrite logic. Use a clean `try_files` directive.

server {
    listen 80;
    server_name example.no;
    root /var/www/html;

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

    location ~ \.php$ {
        fastcgi_pass   127.0.0.1:9000;
        fastcgi_index  index.php;
        fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
        include        fastcgi_params;
    }
}

Hardware Matters: IO Wait is the silent killer

Even with perfect FPM tuning, your database can choke if the disk I/O is slow. This is where the underlying infrastructure becomes critical. Shared hosting often oversells disk I/O, leading to "noisy neighbor" issues where another user's backup script kills your site's performance.

At CoolVDS, we utilize KVM virtualization. This provides true isolation. More importantly, we prioritize low-latency storage subsystems. When your MySQL database is hammering the disk, you need consistent IOPS, not

/// TAGS

/// RELATED POSTS

Surviving the Spike: High-Performance E-commerce Hosting Architecture for 2012

Is your Magento store ready for the holiday rush? We break down the Nginx, Varnish, and SSD tuning s...

Read More →

Automate or Die: Bulletproof Remote Backups with Rsync on CentOS 6

RAID is not a backup. Don't let a typo destroy your database. Learn how to set up automated, increme...

Read More →

Nginx as a Reverse Proxy: Stop Letting Apache Kill Your Server Load

Is your LAMP stack choking on traffic? Learn how to deploy Nginx as a high-performance reverse proxy...

Read More →

Apache vs Lighttpd in 2012: Squeezing Performance from Your Norway VPS

Is Apache's memory bloat killing your server? We benchmark the industry standard against the lightwe...

Read More →

Stop Guessing: Precision Server Monitoring with Munin & Nagios on CentOS 6

Is your server going down at 3 AM? Stop reactive fire-fighting. We detail the exact Nagios and Munin...

Read More →

The Sysadmin’s Guide to Bulletproof Automated Backups (2012 Edition)

RAID 10 is not a backup strategy. In this guide, we cover scripting rsync, rotating MySQL dumps, and...

Read More →
← Back to All Posts