Nginx Cheat Sheet
Core Nginx configuration syntax for serving static files, reverse proxying, load balancing, and TLS termination.
Basic Server Block
Serve static content on a domain.
server { listen 80; server_name example.com www.example.com; root /var/www/example.com; index index.html; location / { try_files $uri $uri/ =404; }}
Reverse Proxy
Forward requests to an upstream application server.
server { listen 80; server_name api.example.com; location / { proxy_pass http://127.0.0.1:3000; 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; }}
Load Balancing
Distribute traffic across multiple backend servers.
upstream backend { least_conn; server 10.0.0.1:3000; server 10.0.0.2:3000; server 10.0.0.3:3000 backup;}server { listen 80; location / { proxy_pass http://backend; }}
TLS / HTTPS
Terminate SSL and redirect HTTP to HTTPS.
server { listen 443 ssl; server_name example.com; ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem; ssl_protocols TLSv1.2 TLSv1.3;}server { listen 80; server_name example.com; return 301 https://$host$request_uri;}
Operational Commands
Managing the nginx process and config.
- nginx -t- Test configuration syntax without applying it
- nginx -s reload- Reload configuration gracefully without dropping connections
- nginx -s stop / quit- Stop immediately (stop) or gracefully after finishing requests (quit)
- systemctl reload nginx- Preferred way to reload on systemd-managed hosts
- error_log / access_log- Directives controlling log destinations and verbosity levels
- gzip on- Enables response compression to reduce bandwidth
Rate Limiting & Burst Control
Throttle abusive clients per IP while allowing legitimate bursts.
http { limit_req_zone $binary_remote_addr zone=api:10m rate=10r/s; limit_conn_zone $binary_remote_addr zone=perip:10m; server { location /api/ { limit_req zone=api burst=20 nodelay; limit_conn perip 10; limit_req_status 429; } }}
Reverse Proxy Caching
Cache upstream responses on disk to cut backend load and latency.
proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=api_cache:10m max_size=1g inactive=60m use_temp_path=off;server { location /api/ { proxy_cache api_cache; proxy_cache_key "$scheme$request_method$host$request_uri"; proxy_cache_valid 200 302 10m; proxy_cache_valid 404 1m; proxy_cache_use_stale error timeout updating; proxy_cache_lock on; add_header X-Cache-Status $upstream_cache_status; proxy_pass http://backend; }}
WebSocket Proxying
Upgrade HTTP connections and keep them alive for real-time apps.
map $http_upgrade $connection_upgrade { default upgrade; '' close;}server { location /ws/ { proxy_pass http://ws_backend; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection $connection_upgrade; proxy_read_timeout 3600s; }}
gRPC Proxying over HTTP/2
Terminate TLS and forward gRPC traffic using the dedicated grpc_pass directive.
server { listen 443 ssl http2; server_name grpc.example.com; ssl_certificate /etc/letsencrypt/live/grpc.example.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/grpc.example.com/privkey.pem; location / { grpc_pass grpc://127.0.0.1:50051; error_page 502 = /error502grpc; }}
Worker & Connection Tuning
Directives that matter most for throughput under high concurrency.
- worker_processes auto- Spawn one worker per CPU core so requests are spread across all cores
- worker_connections- Max simultaneous connections per worker (in the events block); raises the practical concurrency ceiling
- sendfile on / tcp_nopush on- Zero-copy file serving and batching packet headers before sending, reducing syscall overhead
- keepalive_timeout / keepalive_requests- Control how long and how many requests reuse a client connection before it's closed
- upstream keepalive- Pool idle connections to upstream servers so nginx doesn't re-handshake TCP on every proxied request
- open_file_cache- Caches file descriptors and metadata to avoid repeated stat()/open() syscalls for static assets
Always run 'nginx -t' before reloading in production; a syntax error during 'reload' leaves the old worker processes running, which can mask the mistake until the next full restart.