Nginx
High-performance web server and reverse proxy
Nginx is a high-performance web server, reverse proxy, and load balancer that powers a large share of the internet. It is the foundation for many self-hosted proxy setups.
Key features
- Fast reverse proxy
- HTTP and stream load balancing
- Low memory footprint
- Massive deployment base
Pros & cons
Strengths
- Battle-tested at scale
- Very low resource usage
- Huge community knowledge
Trade-offs
- Config syntax takes learning
- No automatic HTTPS
Nginx replaces
Last reviewed Aug 26, 2026 · 816 words
Nginx stopped being the default reverse proxy for self-hosters somewhere around 2020, when Caddy made automatic HTTPS a two-line affair and Traefik made Docker labels the configuration. It has not stopped being the best one for three jobs: serving static files at absurd throughput, proxying raw TCP and UDP with the stream module, and running on the 64 MB of RAM in a router or a Pi Zero. And there is a fourth reason that is not technical: after 22 years, every problem you will ever hit has a Stack Overflow answer with 400 upvotes. If you already know Nginx, there is no compelling case to leave. If you are starting from zero in 2026, start with Caddy and come back when you need one of the three jobs.
The 9 lines you will paste into every site block
Reverse proxying a self-hosted app is the same block every time, and getting it slightly wrong produces bugs that look like the app's fault:
server {
listen 443 ssl;
server_name photos.example.com;
client_max_body_size 0;
location / {
proxy_pass http://127.0.0.1:2283;
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_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}
Each line answers a specific failure. Missing Host and apps generate redirects to 127.0.0.1. Missing X-Forwarded-Proto and apps that check for HTTPS loop forever between http and https. Missing the Upgrade pair and anything with live updates (Home Assistant, Immich, every chat app) breaks silently. client_max_body_size defaults to 1 MB, and a photo upload to Immich failing with 413 is the single most common "Nginx broke my app" report; 0 disables the limit for this host.
Automatic HTTPS is the gap, and there are two ways to close it
Nginx has no built-in certificate management, which is what the catalogue's "no automatic HTTPS" means. Certbot closes it on a bare-metal install:
apt install certbot python3-certbot-nginx
certbot --nginx -d photos.example.com
That edits your server block to add the certificate paths and installs a renewal timer. It works and it has worked for a decade. The other route is Nginx Proxy Manager, which wraps Nginx in a web UI with Let's Encrypt built in and is the right choice if you want Nginx's engine without writing config by hand. The reverse proxy showdown puts all four options side by side; the short version is that NPM is Nginx for people who would otherwise choose Caddy.
Where it beats Caddy and Traefik outright
Static files first. A site of prebuilt HTML on Nginx serves tens of thousands of requests a second on a single core with sendfile on, and the config is 3 lines. Caddy is close; Traefik does not try. Second, the stream block proxies TCP and UDP without caring what protocol is inside, which is how you put a domain in front of a Minecraft server, a mail server or a Postgres instance on the same box that serves HTTP. Traefik can do this with more ceremony; Caddy needs a plugin. Third, memory: the catalogue's 64 MB is real, and an Nginx worker idles around 2 to 5 MB, which is why it is the proxy inside most Docker images that need one.
The Caddy vs Traefik comparison is the one to read if you have decided against Nginx and are picking between the two that replaced it.
The config habits that prevent 3 a.m. debugging
Run nginx -t before every reload, without exception; a typo in one site file takes every site down when the reload fails. Keep one file per site in sites-available with a symlink in sites-enabled, so disabling a site is rm on a link rather than editing a 300-line file. And read the error log at /var/log/nginx/error.log before searching the web; Nginx error messages are precise and name the directive at fault.
What I'd do
New self-hoster with 5 web apps behind one domain: Caddy, and I would not think twice. Existing Nginx setup that works: leave it alone; migration buys nothing. A box that serves a static site, a game server and a couple of apps on 1 GB of RAM: Nginx with certbot, using the site block above as the template, because it is the only one of the three that does all of that without plugins. And anyone who wants Nginx's behaviour but not its config file: Nginx Proxy Manager, which is the honest answer for most people who search for this page. Everything else in the proxy category sits on Nginx's shoulders; you just don't have to hold it up yourself anymore.
Compare Nginx
2 head-to-head comparisons.
Similar reverse proxy & gateways apps
Caddy
Reverse Proxy & GatewaysFast, multi-platform web server with automatic HTTPS
Replaces Nginx, Apache
Traefik
Reverse Proxy & GatewaysCloud-native reverse proxy and load balancer
Replaces HAProxy, AWS ELB
Pi-hole
Reverse Proxy & GatewaysBlackhole for Internet advertisements with a GUI for management
Replaces NextDNS
acme.sh
Reverse Proxy & GatewaysPure shell ACME client for TLS certificates
Replaces Certbot
mitmproxy
Reverse Proxy & GatewaysInteractive HTTPS proxy for inspection and debugging
Replaces Charles Proxy, Fiddler
Kong Gateway
Reverse Proxy & GatewaysCloud-native, fast, scalable API gateway
Replaces AWS API Gateway, Apigee