The Apache Bottleneck is Real
If you are running a high-traffic site on a standard LAMP stack right now, you are likely watching your RAM usage graph look like a hockey stick every time a marketing campaign launches. I've seen it a dozen times: a perfectly good Magento store or Drupal site goes dark because Apache process spawning hit the memory limit.
Apache is great. Itβs flexible. But the pre-fork model is heavy. Every client connection eats a chunk of RAM, whether that client is downloading a 2KB image or processing a complex PHP script. When you hit the C10k barrier (10,000 concurrent connections), your server starts swapping. And swapping is death.
The solution isn't just throwing more hardware at the problem. It's architecture. Specifically, putting Nginx in front of Apache.
Why Nginx?
Nginx (Engine-X) uses an event-driven, asynchronous architecture. Unlike Apache, it doesn't spawn a new process for every connection. It handles thousands of connections in a single worker process with a tiny memory footprint. By placing Nginx as a reverse proxy on port 80, handling the static files (images, CSS, JS), and only passing the heavy PHP requests to Apache (listening on port 8080), you drastically reduce memory overhead.
The "War Story": The Oslo Launch
Last month, we deployed a campaign site for a client in Oslo. We anticipated moderate traffic, but a link on a major Norwegian news outlet sent traffic spiking by 400% in ten minutes. On a standard setup, the server would have melted. Because we had Nginx buffering the requests, the load average stayed below 2.0. The latency to the NIX (Norwegian Internet Exchange) remained flat. If we had relied on pure Apache, we would have been rebooting via KVM console all night.
Configuration Guide: Nginx Reverse Proxy
Assuming you are running CentOS 5.5 or Debian Lenny, here is the battle-tested configuration. We are using Nginx 0.8 series here.
1. Edit Apache Config
First, move Apache off port 80. Edit your httpd.conf or ports.conf:
Listen 127.0.0.1:8080Restart Apache. Your site is now down. Don't panic. That's what Nginx is for.
2. Configure Nginx
Create a new virtual host file in /etc/nginx/sites-available/. Here is the reference implementation we use on our CoolVDS Xen instances:
server {
listen 80;
server_name example.no www.example.no;
# Serve static files directly - huge performance win
location ~* ^.+\.(jpg|jpeg|gif|png|ico|css|zip|tgz|gz|rar|bz2|doc|xls|exe|pdf|ppt|txt|tar|mid|midi|wav|bmp|rtf|js)$ {
root /var/www/example.no/public_html;
expires 30d;
break;
}
# Pass everything else to Apache
location / {
proxy_pass http://127.0.0.1:8080;
proxy_redirect off;
# Essential for logs and apps to see the real IP, not 127.0.0.1
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# Buffer settings to handle slow backend responses without tying up Nginx
client_max_body_size 10m;
client_body_buffer_size 128k;
proxy_connect_timeout 90;
proxy_send_timeout 90;
proxy_read_timeout 90;
proxy_buffer_size 4k;
proxy_buffers 4 32k;
proxy_busy_buffers_size 64k;
proxy_temp_file_write_size 64k;
}
}Run nginx -t to check for syntax errors, then /etc/init.d/nginx reload.
Pro Tip: Ensure your firewall (iptables) allows traffic on port 80 but blocks external access to port 8080. You don't want users bypassing the proxy.
The Infrastructure Factor
Configuration is only half the battle. The underlying virtualization technology dictates how well Nginx performs under load. Many "cheap" VPS providers in Europe use OpenVZ with oversold resources. In those environments, "stolen CPU" time can cause Nginx to stutter, even if your config is perfect.
This is why we standardized on Xen virtualization at CoolVDS. Xen offers strict resource isolation. When you execute a top command, the CPU cycles you see are yours. For low latency applications targeting the Nordic market, consistent I/O performance on our RAID-10 SAS arrays is critical. You can't cache effectively if your disk read speeds fluctuate wildly due to a neighbor's heavy database query.
Compliance & Logging
A quick note on Norwegian privacy laws (Personopplysningsloven). When you configure X-Forwarded-For, you are passing the user's actual IP address to Apache. Ensure your log rotation policies in logrotate.d are configured to archive or purge these logs in accordance with Datatilsynet guidelines. We aren't lawyers, but keeping raw access logs forever is generally a bad idea.
Summary
Nginx isn't magic, but it is the most efficient tool we have in 2010 to handle the C10k problem. It allows you to squeeze enterprise-grade performance out of a standard VPS.
If you are tired of debugging `MaxClients` errors in Apache, it's time to switch. And if you need a server that respects your need for raw, unshared performance, deploy a test instance on CoolVDS today. Our network peering in Oslo ensures your packets get where they need to go, fast.