NGINX: High-Performance Reverse Proxy, Load Balancing, and Edge Caching
NGINX is an event-driven, asynchronous, non-blocking web server, reverse proxy, and Layer 7 load balancer. Originally built to solve the C10k problem (handling 10,000+ concurrent connections), it serves as the primary ingress edge for millions of modern cloud architectures.
⚡ Quick Dive
Load Balancing Algorithms Reference
| Method | Directive | Balancing Behavior | Ideal Use Case |
|---|---|---|---|
| Round Robin | Default (no directive) | Requests distributed sequentially across backend nodes | Identical backend pool capacity |
| Least Connections | least_conn; |
Routes request to server with fewest active connections | Long-lived WebSocket or database queries |
| IP Hash | ip_hash; |
Client IPv4/v6 address determines server selection | Stateful apps requiring Sticky Sessions |
| Generic Hash | hash $request_uri consistent; |
Hashes arbitrary key with consistent hashing | Distributed caching layers |
| Weighted | server srv1 weight=3; |
Proportionately biases traffic allocation | Mixed-capacity hardware pools |
Production Reverse Proxy Template
upstream api_backend {
least_conn;
server 10.0.1.10:8080 weight=3 max_fails=3 fail_timeout=10s;
server 10.0.1.11:8080 weight=2 max_fails=3 fail_timeout=10s;
server 10.0.1.12:8080 backup; # Standby server used only if primaries fail
keepalive 32; # Cache up to 32 idle connections to upstream
}
server {
listen 80;
listen [::]:80;
server_name api.example.com;
return 301 https://$host$request_uri; # Force TLS redirect
}
server {
listen 443 ssl http2;
server_name api.example.com;
ssl_certificate /etc/letsencrypt/live/api.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/api.example.com/privkey.pem;
location / {
proxy_pass http://api_backend;
proxy_http_version 1.1; # Required for keepalive
proxy_set_header Connection "";
# Forward original client headers to backend
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 and Buffers
proxy_connect_timeout 5s;
proxy_read_timeout 60s;
proxy_send_timeout 60s;
proxy_buffer_size 128k;
proxy_buffers 4 256k;
}
}
📖 Extended Guide
1. Reverse Proxy Header Propagation
When Nginx proxies a request, the backend application sees Nginx's internal IP address instead of the end-user's real IP address. Proper header forwarding is critical:
User (203.0.113.195) ──► Nginx (10.0.0.5) ──► Backend App (10.0.1.10)
X-Real-IP $remote_addr: Passes the immediate client's IP.X-Forwarded-For $proxy_add_x_forwarded_for: Appends the client IP to any existing proxy chain (e.g.203.0.113.195, 10.0.0.5).X-Forwarded-Proto $scheme: Informs backend whether user connected overhttporhttps(preventing infinite redirect loops in backend frameworks).
2. Rate Limiting & DoS Mitigation
Protect backend applications from brute-force attacks and traffic spikes using the Leaky Bucket algorithm:
# Define rate limiting zone: 10 requests per second per client IP
limit_req_zone $binary_remote_addr zone=api_limit:10m rate=10r/s;
server {
location /login/ {
# Allow sudden bursts of up to 20 requests without delay
limit_req zone=api_limit burst=20 nodelay;
limit_req_status 429; # Return HTTP 429 Too Many Requests
proxy_pass http://api_backend;
}
}
3. Edge Content Caching Architecture
# Define cache zone in RAM (100MB metadata) pointing to disk storage (10GB max)
proxy_cache_path /var/cache/nginx/proxy levels=1:2 keys_zone=API_CACHE:100m max_size=10g inactive=60m use_temp_path=off;
server {
location /static/ {
proxy_pass http://api_backend;
proxy_cache API_CACHE;
proxy_cache_valid 200 302 10m;
proxy_cache_valid 404 1m;
proxy_cache_use_stale error timeout updating http_500 http_502;
add_header X-Cache-Status $upstream_cache_status;
}
}