Nginx vs Caddy vs Traefik in 2026: HAProxy, Envoy and Which to Pick
For most of my fourteen years in infrastructure, the answer to "which reverse proxy should we put in front of this?" was nginx, unless someone had a specific reason to say otherwise. In 2026 that answer needs more qualifiers. Caddy and Traefik made automatic HTTPS the baseline, nginx shipped its own ACME module, HAProxy grew dynamic backends, Envoy became the default data plane for a lot of Kubernetes gateways, and most of them spent the year shipping security fixes at a pace I have not seen before. This post compares nginx vs Caddy vs Traefik, with HAProxy and Envoy alongside, on the things that decide real deployments: current versions, certificate automation, configuration model, what the published benchmarks do and do not show, Kubernetes after ingress-nginx, and patch cadence. The hands-on nginx setup is in the companion guide, How to Set Up Nginx as a Reverse Proxy With Let's Encrypt.
Nginx vs Caddy vs Traefik at a glance (October 2026)
Versions move weekly at the moment, so here is where each project stood on 31 October 2026, taken from release pages rather than memory.
| Proxy | Latest release | Language, license | Config model | Built-in ACME (Let's Encrypt) |
|---|---|---|---|---|
| nginx | 1.30.6 stable, 1.31.8 mainline (14 and 21 Oct) | C, BSD-2-Clause | Static files, graceful reload | Yes, via the ngx_http_acme_module dynamic module (preview since Aug 2025) |
| Caddy | 2.11.7 (3 Oct) | Go, Apache-2.0 | Caddyfile or JSON, live admin API | Yes, on by default |
| Traefik | 3.7.17 (30 Oct), 2.11.61 still patched | Go, MIT | Providers: Docker labels, Kubernetes, files | Yes, certificate resolvers |
| HAProxy | 3.4.7 (3.4 LTS released 3 Jun 2026, EOL 2031-Q2) | C, GPLv2 | haproxy.cfg plus Runtime API | Yes: early in 3.2, DNS-01 and dns-persist-01 by 3.4 |
| Envoy | 1.40.2 (27 Oct) | C++, Apache-2.0 | xDS APIs from a control plane | No; certificates via files or SDS |
Sources: each project's release page or news page, linked in the table; languages and licenses from the GitHub repositories.
On the public web, nginx is still the reverse proxy you are most likely to meet. W3Techs' web server survey for 31 October 2026 puts nginx on 30.0% of websites, behind Cloudflare's own edge server at 33.0% (which you rent rather than run) and ahead of Apache at 21.2%. Caddy is at 1.2% and Envoy at 0.5%. Traefik and HAProxy do not appear at all, which probably says more about where they sit (behind a CDN or load balancer, or inside a cluster) than about how often they are used.
Which reverse proxy has automatic HTTPS in 2026?
This used to split the field cleanly. Not any more.
Caddy still does it best by default. Put a hostname in a site block and Caddy obtains and renews the certificate, redirects HTTP to HTTPS, and falls back to ZeroSSL if Let's Encrypt fails (since 2.8, only when you set an email). It has supported ACME Renewal Information (ARI) since 2.8 and ACME profiles since 2.10. It also offers on-demand TLS, which issues certificates during the first handshake for names you never listed, and which the docs say must be restricted or it can be abused.
Traefik attaches ACME to routers through certificate resolvers with HTTP-01, TLS-ALPN-01 and DNS-01 challenges and a profile option. Its docs mark the account email as required, store everything in one acme.json file, and say renewal starts 30 days before expiry with an assumed 90-day lifetime (certificatesDuration, default 2160 hours). I could not find ARI mentioned in Traefik's ACME reference.
nginx closed the gap in August 2025, when the NGINX team announced a preview of native ACME support written in Rust. It ships as the nginx-module-acme package from nginx.org, supports HTTP-01 and TLS-ALPN-01, and nginx-acme 0.4.0 added ARI on 20 April 2026. Most nginx installs still use certbot, and that remains a reasonable choice.
HAProxy added "early support" for ACME in 3.2, and the 3.4 announcement of 3 June 2026 describes DNS-01 handling, the new dns-persist-01 challenge, profiles and External Account Binding. Envoy has no ACME client; certificates arrive as files or through the Secret Discovery Service, which in Kubernetes usually means cert-manager.
Why this matters more in 2026 than it did in 2020: Let's Encrypt turned off OCSP in August 2025, stopped expiry emails in June 2025, and its default certificate lifetime drops to 64 days on 10 February 2027 and to 45 days in 2028. Any renewal path that relies on a human noticing an email is already broken. I covered the full schedule in TLS Certificate Lifetimes in 2026.
Config models: static files, Docker labels and APIs
The bigger day-to-day difference is how each proxy learns about your services.
nginx and HAProxy are file-first. You edit a file, run a syntax check, and reload; the old workers finish their requests. HAProxy also has a Runtime API, and 3.4 added add backend to create backends without a reload, currently only on a CLI connection in experimental mode. nginx mainline 1.31.5 added a "control API" build option in September, per the changelog, but the stable branch is still a reload-the-file world.
Caddy's native format is JSON, served by an admin API on localhost:2019; the Caddyfile is a friendlier adapter on top. One detail worth knowing before you put chat or live dashboards behind it: by default Caddy closes WebSocket connections when the config is reloaded, unless you set stream_close_delay.
Traefik is discovery-first. It watches Docker, Kubernetes or a file and builds routes from labels or custom resources, so a container that starts with the right labels is routed and gets a certificate without anyone touching the proxy. Envoy is designed to be driven by a control plane over xDS; you can hand-write its YAML, but almost nobody should.
Here is the same service, app.example.com on port 3000, in three of them:
# Caddyfile for Caddy 2.11.7. HTTPS, the HTTP->HTTPS redirect, HTTP/3
# and WebSocket proxying are all on by default.
app.example.com {
reverse_proxy 127.0.0.1:3000
}
# nginx 1.30.x from nginx.org plus the nginx-module-acme package (preview).
# Adapted from the ngx_http_acme_module docs; I have not run this build locally.
load_module modules/ngx_http_acme_module.so; # main context
http {
resolver 127.0.0.53; # systemd-resolved stub on Ubuntu
acme_issuer letsencrypt {
uri https://acme-v02.api.letsencrypt.org/directory;
state_path /var/cache/nginx/acme-letsencrypt;
accept_terms_of_service;
}
acme_shared_zone zone=ngx_acme_shared:1M;
server {
listen 443 ssl;
http2 on;
server_name app.example.com;
acme_certificate letsencrypt;
ssl_certificate $acme_certificate;
ssl_certificate_key $acme_certificate_key;
ssl_certificate_cache max=2;
location / {
proxy_pass http://127.0.0.1:3000;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
server {
listen 80; # required for HTTP-01
location / { return 301 https://$host$request_uri; }
}
}
# compose.yaml: Traefik v3.7.17 routing a container by its labels.
services:
traefik:
image: traefik:v3.7.17
command:
- --providers.docker=true
- --providers.docker.exposedbydefault=false
- --entryPoints.web.address=:80
- --entryPoints.websecure.address=:443
- --entryPoints.web.http.redirections.entryPoint.to=websecure
- --certificatesresolvers.le.acme.email=ops@example.com # required
- --certificatesresolvers.le.acme.storage=/letsencrypt/acme.json
- --certificatesresolvers.le.acme.httpchallenge.entrypoint=web
ports: ["80:80", "443:443"]
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro # root-equivalent access
- ./letsencrypt:/letsencrypt
app:
image: ghcr.io/example/app:1.4.2
labels:
- traefik.enable=true
- traefik.http.routers.app.rule=Host(`app.example.com`)
- traefik.http.routers.app.entrypoints=websecure
- traefik.http.routers.app.tls.certresolver=le
- traefik.http.services.app.loadbalancer.server.port=3000
The Traefik example shows the trade-off nicely. Discovery is pleasant, but it works by giving the proxy the Docker socket, and Docker's own security docs are clear that access to the daemon should be limited to trusted users. Your internet-facing proxy is now one bug away from the host.
Is Nginx faster than Caddy or Traefik?
Yes, on the benchmarks that exist, and it usually does not matter. I found no recent, independent, well-documented benchmark of all five, so here are the two most transparent ones, with their limits.
| Test | HAProxy | nginx | Traefik | Caddy | Envoy |
|---|---|---|---|---|---|
| Traefik forum rerun, Nov 2025, 4 vCPU AMD, req/s | 25,880 | 25,427 | 18,291 (20,795 with FastProxy) | 14,930 | not tested |
| Same test, p99 latency | 8.0 ms | 8.0 ms | 14.3 ms (11.8 ms) | 16.9 ms | not tested |
Proxy-Benchmarks, 2023, hey on AWS, req/s |
39,437 (2.7.3) | 33,506 (1.22.1) | 25,995 (2.9.8) | 17,984 (2.6.4) | 25,852 (1.22.8) |
Sources: the linked forum thread and GitHub repository. Hardware, versions and defaults differ, so compare within a row, not across rows.
Both put the C proxies ahead. In the 2025 run, Caddy delivered about 59% of nginx's throughput and Traefik about 72%; in 2023 the ratios were 54% and 78%. Both tests proxy tiny responses on a single box with near-default settings, which is the workload where proxy overhead is most visible and least representative. The thread started because a different benchmark had Traefik behind Caddy; the rerun and the 2023 numbers put it ahead, which tells you how much setup matters. Traefik's FastProxy closes some of the gap but is experimental and falls back to the normal proxy for HTTP/2 backends. HAProxy's 3.4 announcement claims "up to 20% higher request rate" on many-core CPUs, without a published baseline.
My rule of thumb: if one node doing fifteen thousand small requests a second is nowhere near your peak, throughput should not decide this. TLS settings, upstream connection reuse, timeouts and logging will move your numbers more than the proxy. Near that line, benchmark your own traffic.
Which reverse proxy is most secure? 2026 was the year of the advisory
I did not expect to write this section. Counting published security fixes per project, 2026 is not a normal year for anyone.
nginx's changelog lists 26 distinct CVE identifiers in 2026 so far, against two in 2025, fixed across eight stable releases (1.28.2 to 1.30.6) and their mainline twins. Some credits point at AI-assisted research: the March release thanks "Calif.io in collaboration with Claude and Anthropic Research" for one of them. Traefik has published 62 GitHub advisories this year (37 rated high or critical) against seven in 2025, and eight of them are in the Kubernetes ingress-nginx provider that Traefik offers as a migration bridge. Envoy went from 10 to 37 and Caddy from zero to 18, six of them fixed in 2.11.1 alone. HAProxy's front page lists two QUIC parsing CVEs from February. I wrote about the wider wave of AI-assisted bug finding in AI Found the Bugs.
Two patterns are worth more than the raw counts. First, the bug classes differ by language. Most of the nginx fixes are buffer overflows, over-reads and use-after-free, and Envoy's list has its share of crashes and use-after-free alongside logic bugs; the Go proxies' fixes are almost all logic: matcher bypasses, auth middleware that fails open, header spoofing. Memory safety removes one class of bug, not the need to patch. Second, how fast you receive fixes depends on where you get the binary. nginx.org shipped the five October CVE fixes on 14 October; Ubuntu's CVE tracker listed them as "Needs evaluation" for 24.04's nginx 1.24 until the backport (USN-8955-1) on 26 October. That twelve-day gap is a packaging decision you are making whether you know it or not.
This is the AI-era version of an old DevOps lesson. When bug discovery gets cheap, the advantage moves to whoever can ship a patched proxy to production fastest, which means pinned versions, automated rebuilds, a staging environment and a rollback you have actually tried.
Which reverse proxy for Kubernetes after ingress-nginx?
The community ingress-nginx controller stopped receiving fixes in March 2026; I covered the retirement and the replacement options in detail in Ingress NGINX Is Retired. The short version by proxy:
- nginx: NGINX Gateway Fabric 2.8.0 (14 October) puts the nginx data plane behind Gateway API.
- Envoy: Envoy Gateway 1.9.3, plus Istio, kgateway and others. Envoy sits under more of these gateways than any single alternative I know of.
- Traefik: implements Ingress, its own CRDs and Gateway API, and its ingress-nginx provider reads existing
nginx.ingress.kubernetes.ioannotations. Useful as a bridge; note the advisory count above. - HAProxy: the HAProxy Kubernetes Ingress Controller is at 3.2.19, and the HAProxy Unified Gateway for Gateway API reached 1.0.10 this month.
- Caddy: no first-party production controller. The caddyserver/ingress repository still describes itself as work in progress, with its last release in January 2025.
So which reverse proxy should you pick?
Pick by operating model, not by benchmark:
- One VM, a handful of sites, nobody wants to think about certificates: Caddy. Fewest lines of config, best HTTPS defaults, HTTP/3 on by default.
- A Docker host where containers come and go: Traefik. Labels on the container are the config. Keep it current, protect the socket.
- An existing nginx estate, static files, caching, a team that reads nginx configs fluently: nginx. Get it from the nginx.org repository if patch speed matters to you, and use certbot or the ACME module.
- Heavy load balancing, TCP and HTTP, detailed health checks, long-lived LTS branches: HAProxy.
- Kubernetes gateways, service mesh, or a fleet driven by a control plane: Envoy, through Envoy Gateway or Istio rather than hand-written YAML.
Mixing is normal: HAProxy or a cloud load balancer at the edge, nginx or Caddy next to the app.
FAQ
Is Caddy faster than Nginx?
No. In the two public benchmarks above, Caddy reached roughly 54 to 59% of nginx's requests per second on small responses. For most sites that difference never shows up, because the application, the database or TLS handshakes are the bottleneck long before the proxy is.
Is Traefik good for production?
Yes, for the Docker and Kubernetes cases it was built for, where routes come from labels and custom resources. The costs are the ones covered above: it needs access to your orchestrator's API, and it published 62 security advisories in 2026, so you need to track releases closely. Its v2.11 branch is still receiving patches if you have not moved to v3.
Does Nginx support automatic HTTPS now?
Partly. The official ngx_http_acme_module, a preview since August 2025, can request and renew Let's Encrypt certificates from inside nginx, including ARI support since nginx-acme 0.4.0. It is a separate dynamic module that you install from nginx.org's packages or build yourself, so most installs still use certbot with its nginx plugin.
Should I use HAProxy or Nginx as a load balancer?
For pure load balancing, especially TCP or many backends with health checks and runtime changes, HAProxy is the more specialised tool and has long LTS branches (3.4 is supported to 2031). If the same box also serves static files, caches responses or terminates a few virtual hosts, nginx does more of that job in one process.
This quarter I would do three things. I would list every reverse proxy we run, with its version and where the binary comes from, because the 2026 advisory rate makes "we installed it in 2023" an incident waiting for a date. I would point one staging service at Let's Encrypt's staging environment, which has issued 64-day certificates since 14 October, and confirm renewal works without anyone watching. And for anything still on ingress-nginx, I would pick the replacement now rather than when the next CVE lands. The choice between nginx, Caddy and Traefik matters much less than having an owner for whichever one you choose.
Related: Ingress NGINX Is Retired: What Replaces It and How to Choose in 2026, TLS Certificate Lifetimes in 2026: 200 Days Now, 47 Days by 2029 and How to Fix 502 Bad Gateway and 504 Gateway Timeout Errors (2026).
I'm Ajay Kumar — I build and operate PandaStack, an open-source Firecracker microVM cloud for AI agents, and write about the infrastructure and tooling around it.
Need this kind of infrastructure work? See what I do or email hello@ajayk.sh.
Related
Docker Compose in Production (2026): Is v5.6 Enough, or Do You Need K8s?
Is Docker Compose good enough for production in 2026? What Compose v5 changed (pre_start init containers, reconciliation, unsupported-key warnings), what a single host still cannot do, how Kamal, Coolify and Swarm compare, and when to move to Kubernetes.
13 minOct 20, 2026Crossplane vs Terraform vs Pulumi in 2026: Control Plane or Plan/Apply?
Crossplane vs Terraform, OpenTofu and Pulumi as of October 2026: Crossplane v2 namespaced resources and function pipelines, CNCF graduation, Pulumi running HCL, Terraform 1.16 and OpenTofu 1.13, how each handles drift, what it costs, and which team fits which tool.
12 minOct 20, 2026Ingress NGINX Is Retired: What Replaces It and How to Choose in 2026
Ingress NGINX stopped receiving fixes in March 2026 after seven CVEs in its final seven weeks. What retirement means, why IngressNightmare mattered, where Gateway API stands at v1.6, and how to pick between Envoy Gateway, Cilium, Istio, NGINX Gateway Fabric, Traefik and kgateway.
13 min