Console Login

Stop Wasting RAM: Migrating from Apache mod_php to PHP-FPM & Nginx

The End of the Apache Monolith: Why You Need PHP-FPM Now

If you are still running your high-traffic Norwegian e-commerce site on Apache 2.2 with mod_php, you are essentially setting your money on fire. I've watched too many sysadmins throw more RAM at a problem that is fundamentally architectural. When Apache spawns a child process in prefork mode, it embeds the PHP interpreter into every single process. Serving a 1KB static CSS file? Congratulations, you just loaded the entire PHP environment to do it. It is inefficient, it is bloated, and in 2011, we have a better way.

With the release of PHP 5.3.3, PHP-FPM (FastCGI Process Manager) is finally part of the core. No more patching. It is time to decouple your web server from your language interpreter. By placing Nginx in front—which uses an asynchronous event-driven architecture—and letting PHP-FPM handle the code execution, you can drop your memory footprint by 40-60% while handling 3x the concurrency. Here is how we build this stack on the newly released CentOS 6.

The Architecture: Nginx + PHP-FPM

Unlike Apache's blocking I/O, Nginx handles thousands of connections with a tiny memory footprint. It passes PHP requests to the FPM daemon via a TCP or Unix socket. This separation allows you to tune the web server for I/O and the application server for CPU, independently.

Step 1: The Repository Setup

CentOS 6 is fresh, but the default repositories are often conservative. For the latest Nginx and PHP builds, we rely on the REMI or EPEL repositories. Do not compile from source unless you enjoy dependency hell.

rpm -Uvh http://download.fedoraproject.org/pub/epel/6/i386/epel-release-6-5.noarch.rpm yum install nginx php-fpm php-common php-mysql php-pecl-apc

Configuration: The Meat and Potatoes

The magic happens in /etc/php-fpm.d/www.conf. Most default configs are set for low-traffic dev boxes, not production servers handling traffic from Oslo to Trondheim.

Optimizing the FPM Pool

The most critical directives are the process manager settings. You have two choices: static or dynamic. For a dedicated VPS where you know exactly how much RAM you have (like our CoolVDS High-Memory instances), static often yields better performance because you avoid the overhead of forking processes under load.

Here is a configuration optimized for a VPS with 2GB RAM dedicated to the web stack:

; /etc/php-fpm.d/www.conf

[www]
listen = 127.0.0.1:9000
listen.allowed_clients = 127.0.0.1
user = nginx
group = nginx

; Choose static for predictable performance
pm = static

; Formula: (Total RAM - OS overhead) / Average PHP Process Size
; Example: (2048MB - 256MB) / 32MB per process ~= 56
pm.max_children = 50

; If using dynamic (safer for shared nodes):
; pm = dynamic
; pm.max_children = 50
; pm.start_servers = 10
; pm.min_spare_servers = 5
; pm.max_spare_servers = 15
 
request_terminate_timeout = 30s
rlimit_files = 131072
rlimit_core = 0

Connecting Nginx

Now, tell Nginx to pass .php requests to the backend. We also want to ensure we aren't passing malicious scripts to the interpreter. Note the try_files directive—it is crucial for security to prevent the "path info" exploit.

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

    # Serve static files directly - blazing fast on CoolVDS SSDs
    location / {
        try_files $uri $uri/ /index.php?$args;
    }

    location ~ \.php$ {
        try_files $uri =404;
        fastcgi_pass   127.0.0.1:9000;
        fastcgi_index  index.php;
        fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
        include        fastcgi_params;
        
        # Performance Tweaks
        fastcgi_buffer_size 128k;
        fastcgi_buffers 256 16k;
        fastcgi_busy_buffers_size 256k;
        fastcgi_temp_file_write_size 256k;
    }
}

The Secret Sauce: APC (Alternative PHP Cache)

If you are not using an opcode cache in 2011, your server is compiling the same PHP script into machine code thousands of times per second. It is senseless. APC stores the compiled bytecode in shared memory.

Pro Tip: Monitor your APC fragmentation. If your apc.shm_size is too small, APC will clear the cache often, causing CPU spikes. For a standard Magento or Drupal installation, start with 128M.

Add this to your /etc/php.d/apc.ini:

extension=apc.so
apc.enabled=1
apc.shm_segments=1
apc.shm_size=128M
apc.ttl=7200
apc.user_ttl=7200
apc.num_files_hint=1024
apc.mmap_file_mask=/tmp/apc.XXXXXX
apc.enable_cli=1

Why Storage I/O is the New Bottleneck

Once you optimize CPU and RAM with Nginx and FPM, the bottleneck moves to the disk. PHP sessions, database writes, and temporary files all hit the drive. Most hosting providers in Norway are still spinning rusty SATA drives at 7200 RPM.

At CoolVDS, we have deployed Enterprise SSD storage across our virtualization clusters. The difference in latency is staggering. While a standard hard drive might give you 100 IOPS (Input/Output Operations Per Second), our SSD arrays push thousands. When you are writing session files for a busy login page, that milliseconds difference adds up to seconds of load time for the user.

Metric Apache Prefork + HDD Nginx FPM + CoolVDS SSD
Concurrency Starts blocking at ~250 users Handles 2,000+ stable
Memory per Process ~35MB ~15MB (FPM average)
Disk Latency 12-15ms < 1ms

Local Compliance and Latency

For Norwegian businesses, hosting abroad introduces legal ambiguity regarding the Personopplysningsloven (Personal Data Act) and adds unnecessary latency. Packets traveling from Frankfurt to Oslo take time. By hosting locally on CoolVDS, you ensure single-digit millisecond ping times to your customers on Telenor and NextGenTel networks, and your data remains within Norwegian jurisdiction, satisfying Datatilsynet requirements.

Do not let legacy software slow you down. The tools to serve traffic faster are here today. Backup your httpd.conf, shut down Apache, and fire up Nginx.

Ready to test the raw speed of SSD-backed PHP-FPM? Spin up a CoolVDS instance in Oslo today and see the difference in `top`.