Stop the Swap Death: Nginx Reverse Proxy Architecture for High-Traffic Norwegian Sites
It is 3:00 AM. Your monitoring system is screaming. Your client, a popular Oslo-based e-commerce store, just launched a holiday campaign. The traffic isn't even a DDoS; it's legitimate customers. Yet, your load average is 25.0, your RAM is exhausted, and the server is swapping so hard the disk heads are practically welding themselves together.
The culprit? Likely Apache's prefork MPM (Multi-Processing Module). Every connection spawns a process. Every process eats RAM. When you run out of RAM, you hit the disk. When you hit the disk, you die.
I have seen this scenario play out in data centers from Bergen to Trondheim. The solution isn't always throwing more hardware at the problem—it's architecture. Specifically, putting Nginx in front of your application server.
The Architecture: Why Reverse Proxy?
Apache is a fantastic Swiss Army knife, but it is heavy. Nginx is a scalpel. It uses an event-driven, asynchronous architecture. It doesn't spawn a new process for every connection. It can handle thousands of concurrent keep-alive connections with a tiny memory footprint.
In this setup, Nginx faces the public internet (port 80/443). It serves static assets (images, CSS, JS) instantly from memory. It only passes heavy, dynamic requests (PHP, Python) to the backend Apache server running on a local port (e.g., 8080). This keeps the heavy Apache processes free for what they do best: processing code.
Here is how we build this stack on a standard CoolVDS instance running CentOS 6.3.
Step 1: Install Nginx (The Right Way)
Don't just use the default repo; it's often outdated. We want the latest stable branch. First, let's add the EPEL repository or the direct Nginx repo.
rpm -Uvh http://nginx.org/packages/centos/6/noarch/RPMS/nginx-release-centos-6-0.el6.ngx.noarch.rpm
Now, install the server:
yum install nginx
chkconfig nginx on
Step 2: Configure the Backend (Apache)
We need Apache to stop listening on the public IP and retreat to localhost. Open your /etc/httpd/conf/httpd.conf.
# /etc/httpd/conf/httpd.conf
# Change the Listen directive
Listen 127.0.0.1:8080
# Keep KeepAlive OFF for the backend to save RAM.
# Nginx handles the persistence with the client.
KeepAlive Off
Critical Warning: When Nginx proxies requests, Apache sees all traffic coming from 127.0.0.1. This breaks your access logs and security blocking. You must install mod_rpaf (Reverse Proxy Add Forward) to map the X-Forwarded-For header back to the real IP.
yum install mod_rpaf
Step 3: The Nginx Reverse Proxy Configuration
This is where the magic happens. We will configure Nginx to handle the heavy lifting. Open /etc/nginx/conf.d/default.conf (or create a new vhost file).
Basic Global Tuning
First, ensure your main nginx.conf utilizes your hardware. On a CoolVDS instance, you have access to dedicated CPU cores—use them.
worker_processes auto;
worker_rlimit_nofile 100000;
The Proxy Block
Here is a production-ready configuration block for handling dynamic content securely.
server {
listen 80;
server_name example.no www.example.no;
root /var/www/html;
# 1. Serve Static Files Directly (No Apache needed)
location ~* \.(jpg|jpeg|gif|png|css|js|ico|xml)$ {
access_log off;
log_not_found off;
expires 30d;
}
# 2. Deny access to hidden files (.htaccess)
location ~ /\. {
deny all;
access_log off;
log_not_found off;
}
# 3. Pass PHP/Dynamic requests to Apache
location / {
proxy_pass http://127.0.0.1:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# Timeouts for slow backend scripts
proxy_connect_timeout 60;
proxy_send_timeout 90;
proxy_read_timeout 90;
# Buffer settings to handle large headers
proxy_buffer_size 128k;
proxy_buffers 4 256k;
proxy_busy_buffers_size 256k;
}
}
Test your configuration before reloading. A syntax error here takes your site down.
service nginx configtest
service nginx reload
The Bottleneck You Forgot: Disk I/O
You can optimize your Nginx buffers all day, but if your server is writing logs or reading database rows from a spinning rust hard drive, your latency will suffer. This is especially true in a reverse proxy setup where logging happens twice (once on Nginx, once on Apache) and database activity is heavy.
Pro Tip: Check your I/O wait with thetopcommand. If thewa(wait) percentage is consistently above 10%, your disk is the problem, not your config.
This is where infrastructure choice becomes a business decision. At CoolVDS, we have standardized on pure SSD storage for our Norwegian infrastructure. In 2012, many providers are still over-provisioning SATA drives. The difference in random read/write speeds between a standard VPS and our SSD VPS is roughly 20x. For a database-heavy site, that is the difference between a 200ms load time and a 2s load time.
Compliance and Latency in Norway
Beyond raw speed, location matters. If your primary user base is in Oslo or Stavanger, hosting in Germany or the US adds unavoidable network latency—typically 30-100ms round trip. By utilizing CoolVDS's Oslo datacenter, you drop that latency to <5ms via NIX (Norwegian Internet Exchange).
Furthermore, keeping data within Norwegian borders simplifies compliance with the Personal Data Act (Personopplysningsloven) and satisfies Datatilsynet requirements regarding data sovereignty. Don't risk legal headaches just to save 50 kroner a month on hosting.
Summary of Benefits
| Feature | Apache Only | Nginx + Apache (CoolVDS) |
|---|---|---|
| Memory Usage | High (Process per user) | Low (Event-driven) |
| Static File Speed | Slow (Context switching) | Instant (Sendfile syscall) |
| Concurrency | Limited by RAM | 10,000+ Connections |
Configuring a reverse proxy is the single most effective change you can make to your server stack today. It stabilizes your resource usage and prepares your infrastructure for scale.
Ready to drop your load times? Don't let legacy hardware bottle up your new configuration. Deploy a test instance on CoolVDS today and experience the power of local SSD hosting.