Overview
Pick Caddy for any new server where automatic TLS is the priority and the configuration fits a Caddyfile. Caddy provisions and renews certificates from Let’s Encrypt and ZeroSSL with zero operator action; nginx requires Certbot, a cron job, and manual reload hooks. Pick nginx when the team has years of nginx configuration knowledge, the workload needs a specific module (ModSecurity, Lua, sticky sessions), or the deployment sits behind a CDN that terminates TLS anyway. The TLS automation gap is the main reason Caddy wins for solo operators and small teams. See nginx-config for nginx pattern reference.
When Caddy wins
Caddy is the right pick when operational simplicity and automatic TLS matter most.
- Automatic TLS:
Caddyfilewith a hostname triggers ACME certificate provisioning, renewal, and hot reload with no cron job or Certbot. - Zero-downtime certificate rotation: Caddy reloads TLS configuration without dropping connections.
- HTTP/2 and HTTP/3 by default: no flag to set; Caddy enables QUIC transport automatically where supported.
- Caddyfile syntax is declarative and terse; a reverse proxy with TLS is three lines. An equivalent nginx config with Certbot integration is 30+ lines across multiple files.
- JSON config API: Caddy exposes a REST API for live configuration changes without reloads; useful for dynamic upstreams in containerized environments.
- Built-in basic auth, request rewriting, and header manipulation without third-party modules.
- Single binary with no runtime dependencies; easy to embed in containers.
When nginx wins
nginx is the right pick when operational depth or module breadth is required.
- Module ecosystem: ModSecurity (WAF), OpenResty (Lua scripting),
ngx_http_auth_request_module, sticky load balancing, and dozens of community modules exist only for nginx. - Configuration granularity: nginx exposes every connection parameter (keepalive timeouts, upstream health check intervals, buffer sizes, proxy buffering) with documented semantics. Caddy’s documentation for equivalent tuning is thinner.
- Operational familiarity: most infrastructure engineers know nginx. Hiring, runbooks, and Stack Overflow coverage favor nginx overwhelmingly.
- Kubernetes Ingress: the
ingress-nginxcontroller is the default in most cluster setups; Caddy’s ingress support is less mature. - Static file serving at very high concurrency: nginx’s event model and sendfile support are highly tuned; at 100k+ concurrent connections, nginx has more published tuning art.
- When TLS terminates at a CDN (Cloudflare, Fastly): the automatic TLS advantage disappears and nginx’s control advantage remains. See aws-vs-cloudflare.
Trade-offs at a glance
| Dimension | Caddy | nginx |
|---|---|---|
| Automatic TLS | Built-in ACME | Certbot + cron required |
| HTTP/3 (QUIC) | Default | Module; nginx Plus or recompile |
| Config syntax | Caddyfile (terse) or JSON API | Declarative blocks; verbose |
| Live config reload | JSON API; no process restart | nginx -s reload; brief connection drop |
| Module ecosystem | Limited; Go plugins | C modules; very broad |
| WAF | No native WAF | ModSecurity |
| Kubernetes Ingress | Limited controller support | ingress-nginx is the default |
| Static file perf | Good | Best-in-class at high concurrency |
| Container footprint | Single binary | Multi-package with dynamic modules |
| Documentation depth | Improving; still gaps | Extensive; 15+ years of guides |
| License | Apache 2.0 | BSD (open source) / nginx Plus (paid) |
Migration cost
nginx-to-Caddy is feasible for most simple proxy configs; Caddy-to-nginx is straightforward given nginx’s flexibility.
- nginx to Caddy: map
serverblocks to Caddyfile site blocks. Rewritelocationdirectives as Caddyhandleorrouteblocks. Lua scripts and ModSecurity rules require alternative approaches (move WAF logic to Cloudflare, rewrite Lua as a sidecar service). Plan one engineer-day per site for simple proxies; one week for complex multi-upstream configs. - Caddy to nginx: generate or write
serverblocks for each Caddyfile site. Add Certbot for TLS. The reverse is rarely blocked on feature gaps. Plan half a day per site. - When migrating between servers, verify technical signals (canonical URLs, redirects, HSTS headers) are replicated exactly before switching DNS.
Recommendation
- New VPS or bare-metal server for a small product: Caddy. Automatic TLS alone is worth the switch.
- Kubernetes cluster with standard ingress: nginx via
ingress-nginx. Caddy’s ingress is not production-ready for most setups. - WAF requirement on the origin: nginx with ModSecurity, or offload WAF to Cloudflare (see cloudflare).
- CDN-fronted deployment where Cloudflare terminates TLS: either works; lean toward nginx for ecosystem reasons.
- Team with zero existing nginx knowledge: Caddy; the learning curve is lower.
- High-traffic static asset delivery: nginx with
sendfile onand tuned worker connections.