Nginx Complete Guide | Reverse Proxy· Load Balancing
이 글의 핵심
A complete Nginx guide: internals (event loop, master/worker model, config inheritance), load-balancing algorithms, production patterns (keepalive pools, rate limits, graceful reload), plus static files, reverse proxy, SSL/TLS, caching, gzip, and a full-stack example.
What this post covers
This is a complete guide to building a high-performance web server with Nginx. After a short internals section (event loop, master/worker model, configuration inheritance, upstream algorithms, production patterns), it walks through installation, reverse proxying, load balancing, SSL/TLS, caching, and tuning?�with practical examples.
From the field: After replacing Apache with Nginx, we increased concurrent capacity by about 5× and cut memory usage by roughly 60%.
Introduction: ?�Our web server feels slow??
Real-world scenarios
Scenario 1: Traffic spikes make the site slow
Apache often struggles past roughly 1,000 concurrent users in common configurations. Nginx routinely handles 10,000+ connections.
Scenario 2: Static file serving is slow
The application server is serving static assets. Let Nginx serve them directly?�it is much faster.
Scenario 3: SSL setup feels complicated
Let’s Encrypt can feel fiddly. Certbot plus the Nginx plugin makes certificate issuance and renewal straightforward.
1. What is Nginx?
Key characteristics
Nginx is a high-performance web server and reverse proxy.
Common use cases:
- Web server: static file serving
- Reverse proxy: fronting backends
- Load balancer: distributing traffic
- SSL termination: handling HTTPS
- Caching: caching upstream responses
Performance (order-of-magnitude, not a benchmark):
- Concurrent connections: 10,000+
- Memory: on the order of ~2.5 MB per worker (typical baseline)
2. Internals: event loop, workers, inheritance, load balancing & production patterns
If you only ever copy snippets, you will hit tuning ceilings and painful incidents. This section ties together the process model, event-driven I/O, configuration contexts, upstream algorithms, and production operating patterns.
Event-driven architecture
Traditional thread/process-per-connection servers allocate resources per request. As concurrency grows, context switching and memory overhead dominate. Each Nginx worker runs an event loop and can handle many connections with few processes.
- Event modules: On Linux, Nginx uses
epoll; on BSD/macOS,kqueue.events { use epoll; }selects that path explicitly (when supported). - One worker, many connections: A worker only does work when sockets are ready. Non-blocking sockets plus kernel readiness notifications avoid blocking the whole process.
sendfile: Reduces copies when moving data from disk to socket?�important for static files.worker_connections: Per-worker cap on simultaneous connections. Rough capacity is related toworker_processes × worker_connections, but you must also align file descriptor limits (ulimit -n) and real traffic patterns.
This is why Nginx scales toward C10K-class concurrency. CPU-heavy TLS handshakes and large bodies still concentrate load on workers?�so tune worker count, hardware, and TLS session resumption together.
Worker process model
Nginx splits responsibilities between a master and worker processes.
- Master: Reads configuration, forks workers, and manages lifecycle. Privileged steps (e.g., binding to port 80) typically happen before workers handle traffic.
- Workers: Run the actual request path?�HTTP, reverse proxying, cache I/O, etc.
worker_processes autois a common choice to track CPU cores. - Graceful reload:
nginx -s reload/SIGHUPreplaces workers with a new configuration without dropping in-flight work in the common case?�still validate timeouts and upstream behavior after changes. - Shutdown signals:
SIGTERM/SIGQUITrequest graceful shutdown;SIGKILLis immediate. Check what your systemd unit or deploy script sends.
Workers do not share application memory. Shared caches usually mean OS page cache or an external store (Redis, etc.).
Configuration inheritance and merging
Nginx configuration is a tree of contexts: main ??events, http ??server ??location (plus upstream, mail, etc., when used).
- Inheritance: A directive in
http(e.g.,gzip on) applies to nestedserverblocks unless overridden lower in the tree. include: Splits files but merges into one logical tree?�think ?�composition,??not isolation.locationmatching: Exact=??longest prefix ??if^~wins, skip regex ??first matching regex~/~*. Heavyifusage is hard to reason about; prefermapand explicitlocationsplits when possible.default_server: Chooses the defaultserverblock whenHostdoes not match?�important for multi-tenant setups.
Use nginx -t and small, reviewable includes?�otherwise ?�what did the parent block leave on???becomes guesswork.
Load-balancing algorithms (deep dive)
The upstream algorithm should match backend load shape and session stickiness needs.
| Method | Summary | When it shines |
|---|---|---|
| Default (round robin) | Rotate in order | Similar backends, similar per-request cost |
least_conn | Pick fewest active connections | Variable upstream latency, long-lived connections |
ip_hash | Sticky by client IP | Local session state (watch NAT and mobile IP churn) |
hash ??consistent | Consistent hashing ring | Cache sharding; smoother moves when nodes change |
random two | Pick two at random, then apply a rule (e.g., least_conn) | Open-source option since 1.15+ |
Combine with weight, down, backup, and passive health via max_fails / fail_timeout. Active health checks are often Nginx Plus, another LB, or a service mesh.
upstream api {
least_conn;
server 10.0.0.1:8080 max_fails=3 fail_timeout=30s;
server 10.0.0.2:8080 max_fails=3 fail_timeout=30s;
server 10.0.0.3:8080 backup;
}
upstream cache_nodes {
hash $request_uri consistent;
server 10.0.0.10:11211;
server 10.0.0.11:11211;
}
Production Nginx patterns
- TLS termination + upstream keepalive: HTTPS to clients, HTTP inside the DC is common; pair with upstream connection pools (
proxy_http_version 1.1, clearConnection,keepaliveinsideupstream) to avoid reconnect storms to backends. proxy_next_upstream: Decide which errors/timeouts retry on another peer. Be careful with non-idempotent requests?�pair settings withnon_idempotentrules where appropriate.- Rate limiting:
limit_req_zone/limit_reqfor abuse;limit_connfor concurrent connections per key. - Observability:
stub_status(if built-in), exporters, structured access logs (log_formatJSON) for latency and cache hit ratio. - Shipping config: Always
nginx -tbeforereload. Store configs in Git and align with IaC to avoid snowflake servers.
The hands-on sections below (load balancing, SSL, caching) are where these ideas become concrete nginx.conf snippets.
3. Installation
Ubuntu
sudo apt update
sudo apt install nginx
# Start
sudo systemctl start nginx
# Enable on boot
sudo systemctl enable nginx
# Check status
sudo systemctl status nginx
Docker
docker run -d -p 80:80 nginx:latest
4. Basic configuration
nginx.conf
# /etc/nginx/nginx.conf
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent"';
access_log /var/log/nginx/access.log main;
sendfile on;
tcp_nopush on;
keepalive_timeout 65;
gzip on;
include /etc/nginx/conf.d/*.conf;
}
5. Static file serving
# /etc/nginx/conf.d/default.conf
server {
listen 80;
server_name example.com;
root /var/www/html;
index index.html;
location / {
try_files $uri $uri/ =404;
}
location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ {
expires 1y;
add_header Cache-Control "public, immutable";
}
}
6. Reverse proxy
Basic setup
server {
listen 80;
server_name api.example.com;
location / {
proxy_pass http://localhost:8000;
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;
}
}
WebSocket
location /ws {
proxy_pass http://localhost:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
7. Load balancing
For algorithm trade-offs and max_fails / backup, see section 2. The snippets below are quick copy-paste references.
Round Robin (default)
upstream backend {
server backend1.example.com;
server backend2.example.com;
server backend3.example.com;
}
server {
listen 80;
location / {
proxy_pass http://backend;
}
}
Least connections
upstream backend {
least_conn;
server backend1.example.com;
server backend2.example.com;
}
IP hash (sticky sessions)
upstream backend {
ip_hash;
server backend1.example.com;
server backend2.example.com;
}
Weighted servers
upstream backend {
server backend1.example.com weight=3;
server backend2.example.com weight=2;
server backend3.example.com weight=1;
}
Consistent hash (hash + consistent)
Useful when you want stable mapping across nodes (e.g., cache sharding) with less churn when the set changes.
upstream shard {
hash $request_uri consistent;
server 10.0.0.1:8080;
server 10.0.0.2:8080;
}
random two (open source 1.15+)
Pick two backends at random, then send to the better candidate (here, fewer active connections).
upstream backend {
random two least_conn;
server backend1.example.com;
server backend2.example.com;
server backend3.example.com;
}
8. SSL/TLS
Let’s Encrypt
# Install Certbot
sudo apt install certbot python3-certbot-nginx
# Obtain certificates
sudo certbot --nginx -d example.com -d www.example.com
# Test renewal
sudo certbot renew --dry-run
SSL server block
server {
listen 443 ssl http2;
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;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
location / {
proxy_pass http://localhost:8000;
}
}
# HTTP ??HTTPS redirect
server {
listen 80;
server_name example.com;
return 301 https://$server_name$request_uri;
}
9. Caching
Proxy cache
proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=my_cache:10m max_size=1g inactive=60m;
server {
location / {
proxy_cache my_cache;
proxy_cache_valid 200 60m;
proxy_cache_valid 404 1m;
proxy_cache_bypass $http_cache_control;
add_header X-Cache-Status $upstream_cache_status;
proxy_pass http://backend;
}
}
10. Performance tuning
Gzip compression
gzip on;
gzip_vary on;
gzip_min_length 1024;
gzip_types text/plain text/css text/xml text/javascript
application/json application/javascript application/xml+rss;
Connection tuning
# Worker processes
worker_processes auto;
# Connections
events {
worker_connections 2048;
use epoll;
}
# Keepalive
keepalive_timeout 65;
keepalive_requests 100;
Upstream keepalive (backend connection pool)
Opening a new TCP connection per request to backends adds latency and can exhaust local ports. For HTTP/1.1 upstream pools, set keepalive on the upstream and clear Connection on the proxy hop.
upstream api {
server 127.0.0.1:8080;
keepalive 64;
}
server {
location / {
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_pass http://api;
}
}
Buffer sizes
client_body_buffer_size 10K;
client_header_buffer_size 1k;
client_max_body_size 8m;
large_client_header_buffers 2 1k;
11. Full-stack example
The following is a sample Nginx configuration for a typical app.
# /etc/nginx/conf.d/app.conf
upstream frontend {
server localhost:3000;
}
upstream backend {
server localhost:8000;
server localhost:8001;
server localhost:8002;
}
# HTTP ??HTTPS
server {
listen 80;
server_name myapp.com www.myapp.com;
return 301 https://$server_name$request_uri;
}
# HTTPS
server {
listen 443 ssl http2;
server_name myapp.com www.myapp.com;
ssl_certificate /etc/letsencrypt/live/myapp.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/myapp.com/privkey.pem;
# Frontend (React)
location / {
proxy_pass http://frontend;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
# Backend API
location /api {
proxy_pass http://backend;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
# CORS
add_header Access-Control-Allow-Origin *;
add_header Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS";
}
# Static assets
location /static {
alias /var/www/static;
expires 1y;
add_header Cache-Control "public, immutable";
}
}
Connecting this to interviews and your resume
Being able to explain reverse proxying, SSL, and caching from real operations experience helps in infrastructure and backend interviews. For CS and systems-style questions, see the [coding test & interview strategy guide](/en/blog/coding-test-strategy-guide/; for how to phrase this on a resume, see the [developer job hunting guide](/en/blog/developer-job-hunting-practical-tips/.
Summary and checklist
Key takeaways
- Nginx: high-performance web server
- Reverse proxy: sits in front of backends
- Load balancing: spreads traffic across instances
- SSL/TLS: HTTPS for users and upstreams
- Caching: cache responses to reduce load
- Scale: designed for very high concurrent connection counts
Production checklist
- Install Nginx
- Configure reverse proxy
- Set up load balancing
- Obtain SSL certificates
- Configure caching
- Tune performance
- Add monitoring
Related reading
- [Kubernetes practical guide](/en/blog/kubernetes-practical-guide/
- [Docker Compose complete guide](/en/blog/docker-compose-complete-guide/
- [Terraform practical guide](/en/blog/terraform-practical-guide/
Keywords covered in this post
Nginx, Web Server, Reverse Proxy, Load Balancing, SSL, Performance, DevOps
Frequently asked questions (FAQ)
Q. Nginx vs Apache?�which is better?
A. Nginx is generally faster and more memory-efficient. For most new projects, Nginx is the recommended default.
Q. Can it serve dynamic content?
A. Nginx is optimized for static files. Proxy dynamic work to a backend application server.
Q. Is it free?
A. Yes?�the open-source Nginx is free. Nginx Plus is the paid enterprise offering.
Q. Is it safe for production?
A. Yes. Many organizations?�including large consumer and enterprise sites?�run Nginx in production.
?�주 묻는 질문 (FAQ)
Q. ???�용???�무?�서 ?�제 ?�나??
A. Nginx guide: event loop & workers, config inheritance, load-balancing algorithms, production patterns?�plus reverse proxy???�무?�서????본문???�제?� ?�택 가?�드�?참고???�용?�면 ?�니??
Q. ?�행?�로 ?�으�?좋�? 글?�?
A. �?글 ?�단???�전 글 ?�는 관??글 링크�??�라가�??�서?��?배울 ???�습?�다. C++ ?�리�?목차?�서 ?�체 ?�름???�인?????�습?�다.
Q. ??깊이 공�??�려�?
A. cppreference?� ?�당 ?�이브러�?공식 문서�?참고?�세?? 글 말�???참고 ?�료 링크???�용?�면 좋습?�다.
같이 보면 좋�? 글 (?��? 링크)
??주제?� ?�결?�는 ?�른 글?�니??
- [Kubernetes Practical Guide | Pods· Deployments](/en/blog/kubernetes-practical-guide/
- [Docker Compose Complete Guide | Multi-Container Apps](/en/blog/docker-compose-complete-guide/
- [Coding Test Complete Preparation Complete Guide](/en/blog/coding-test-strategy-guide/
- [Developer Job Hunting Guide | Resume· Portfolio](/en/blog/developer-job-hunting-practical-tips/
??글?�서 ?�루???�워??(관??검?�어)
Nginx, Web Server, Reverse Proxy, Load Balancing, SSL, Performance, DevOps ?�으�?검?�하?�면 ??글???��????�니??