Reverse proxy cheatsheet.
Basic proxy
server {
listen 80;
server_name api.example.com;
location / {
proxy_pass http://127.0.0.1:8000;
proxy_http_version 1.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;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
Upstream block (load balancer)
upstream app {
server 10.0.0.1:8000;
server 10.0.0.2:8000;
server 10.0.0.3:8000 backup;
keepalive 32;
}
server {
location / {
proxy_pass http://app;
proxy_http_version 1.1;
proxy_set_header Connection ""; # required for keepalive
}
}
Load balancing methods
upstream app {
# default: round-robin
least_conn; # least connections
ip_hash; # sticky by IP
hash $request_uri consistent; # consistent hashing
server 10.0.0.1 weight=3;
server 10.0.0.2 weight=1;
server 10.0.0.3 max_fails=3 fail_timeout=30s;
}
Path rewrite in proxy_pass
# /api/users → /users on backend
location /api/ {
proxy_pass http://app/; # trailing / strips /api/
}
# /api/users → /api/users on backend
location /api/ {
proxy_pass http://app; # no trailing /
}
The trailing slash matters.
Headers
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;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Port $server_port;
proxy_set_header X-Request-ID $request_id;
App must trust X-Forwarded-* only from known proxies.
WebSocket / HTTP upgrade
location /ws/ {
proxy_pass http://app;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_read_timeout 86400;
proxy_send_timeout 86400;
}
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
Buffering
proxy_buffering on; # default
proxy_buffer_size 16k;
proxy_buffers 8 16k;
proxy_busy_buffers_size 32k;
# Disable for SSE / streaming:
location /stream {
proxy_buffering off;
proxy_cache off;
proxy_set_header Connection '';
proxy_http_version 1.1;
chunked_transfer_encoding off;
proxy_pass http://app;
}
Timeouts
proxy_connect_timeout 60s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;
client_body_timeout 60s;
client_header_timeout 60s;
send_timeout 60s;
keepalive_timeout 65;
For long-running APIs / uploads, increase appropriately.
Body size
client_max_body_size 10m;
Default 1m. Increase for uploads.
proxy_redirect
proxy_redirect http://backend/ https://example.com/;
Rewrite redirect responses from backend.
Health checks
Open source nginx: passive only (max_fails, fail_timeout).
Nginx Plus: active health checks.
Alternative: nginx-haproxy combo, or use Kubernetes services.
Retries
proxy_next_upstream error timeout http_502 http_503 http_504;
proxy_next_upstream_tries 3;
proxy_next_upstream_timeout 30s;
Retry on errors against next upstream.
Backend selection by header / cookie
map $http_x_canary $upstream {
default app-stable;
"1" app-canary;
}
upstream app-stable { server 10.0.0.1; }
upstream app-canary { server 10.0.0.2; }
server {
location / {
proxy_pass http://$upstream;
}
}
Connection pooling
upstream app {
server 10.0.0.1:8000;
keepalive 64;
keepalive_requests 1000;
keepalive_timeout 60s;
}
server {
location / {
proxy_pass http://app;
proxy_http_version 1.1;
proxy_set_header Connection "";
}
}
SSL to backend
upstream app {
server backend.example.com:443;
}
location / {
proxy_pass https://app;
proxy_ssl_server_name on;
proxy_ssl_verify off; # or on with proper certs
proxy_ssl_session_reuse on;
}
gRPC
server {
listen 50051 http2;
location / {
grpc_pass grpc://backend:50052;
grpc_set_header X-Real-IP $remote_addr;
}
}
Common mistakes
- Forgetting
proxy_http_version 1.1→ no keepalive, no websocket. - Missing trailing
/inproxy_pass→ wrong path. - Trusting
X-Forwarded-Forfrom untrusted source. proxy_buffering onfor SSE → response delayed.Hostheader lost withoutproxy_set_header Host.
Read this next
If you want my reverse-proxy templates, they’re at rajpoot.dev .
Building something AI-, backend-, or data-heavy and want a second pair of eyes? I do consulting and freelance work — see my projects and ways to reach me at rajpoot.dev .