Web Serversintermediate

Caddy vs Traefik

Caddy vs Traefik compared on automatic HTTPS, Caddyfile vs Docker labels, DNS challenges, plugins, Kubernetes, middlewares and observability, using Caddy 2.11.7 and Traefik 3.7.16.

Quick Answer

Pick Caddy if you want the shortest path to a correct HTTPS reverse proxy or web server: a few lines of Caddyfile, certificates from Let's Encrypt or ZeroSSL by default, and a live JSON admin API. Pick Traefik if routes should come from Docker labels or Kubernetes objects and change as containers come and go. Caddy can do labels and Kubernetes only through plugins; Traefik cannot serve static files or PHP on its own.

Last updated October 25, 2026. Covers Caddy v2.11.7 (3 Oct 2026) and the 2.11.6 hardening release, and Traefik v3.7.16 and v2.11.60 (20 Oct 2026), with the v3.7 ACME, provider and middleware docs.

Feature comparison of Caddy vs Traefik
FeatureCaddyTraefik
Licence
Apache-2.0
MIT
Latest Release (Oct 2026)
v2.11.7 (3 Oct 2026)
v3.7.16 (20 Oct 2026); v2.11.60 still patched
Configuration Model
Caddyfile or native JSON, changeable live via admin API
Dynamic providers: labels, Kubernetes objects, KV stores, files
Automatic HTTPS
Default on: Let's Encrypt + ZeroSSL fallback, internal CA for local names
Opt-in per router via a certificate resolver
ACME Challenges
HTTP-01 and TLS-ALPN-01 by default; DNS-01 with plugin
HTTP-01, TLS-ALPN-01, DNS-01
DNS-01 Providers
caddy-dns plugins, community-maintained
Built in via lego (one provider per resolver)
Docker Label Auto-Discovery
Via third-party caddy-docker-proxy plugin
Kubernetes Support
caddyserver/ingress controller (WIP)
Ingress, Gateway API, IngressRoute CRDs, ingress-nginx provider
Static Files / PHP
Yes: file_server, php_fastcgi, templates
No built-in file server (third-party Statiq plugin)
Built-in Auth
basic_auth, forward_auth, mTLS client_auth
BasicAuth, DigestAuth, ForwardAuth (OIDC/JWT in Traefik Hub)
Rate Limiting
Plugin (caddy-ratelimit)
Built-in RateLimit middleware (distributed in Hub)
TCP / UDP Proxying
Plugin (caddy-l4, experimental)
Yes, TCP (HostSNI, passthrough) and UDP routers
Extensions
Go modules compiled in with xcaddy
Plugin catalog and local plugins (experimental)
Runtime API
Full read/write config API (/load, /config)
Read API behind the dashboard
Metrics / Tracing
Prometheus /metrics, OTLP metrics, OpenTelemetry tracing
Access logs, metrics incl. OTLP, tracing

Caddy

Apache-2.0-licensed web server and reverse proxy written in Go, known for automatic HTTPS, a short Caddyfile syntax and a JSON admin API that applies config changes without downtime.

Pros

  • HTTPS by default: public names get certificates from Let's Encrypt with ZeroSSL as automatic fallback, and HTTP redirects to HTTPS
  • Local and internal hostnames get certificates from Caddy's own internal CA, so even dev sites run on HTTPS
  • A full web server too: file_server, php_fastcgi, templates, encode and forward_auth are standard directives
  • Admin API on localhost:2019 swaps the whole config or one path of it with zero downtime and rolls back on failure
  • Instances that share storage coordinate certificate management as a cluster, so multi-node setups need no extra tool
  • On-Demand TLS issues certificates during the first handshake, which suits SaaS products with customer domains

Cons

  • DNS-01 and wildcard certificates need a caddy-dns provider plugin, which means a custom build with xcaddy or the download page
  • No built-in Docker label discovery; caddy-docker-proxy is a third-party plugin
  • Rate limiting and raw TCP/UDP proxying are plugins (caddy-ratelimit, caddy-l4), and caddy-l4 warns of breaking changes
  • The Kubernetes ingress controller is described by its own repo as work in progress
  • 2.11.6 shipped regressions in streaming and HTTP/2 that 2.11.7 fixed two days later, so test patch upgrades

Best For

Single servers and VPSs, static sites and PHP apps, SaaS products that need certificates for customer domains, and anyone who wants HTTPS working with the least config.

Traefik

MIT-licensed cloud-native reverse proxy and load balancer written in Go that builds its routes dynamically from providers such as Docker labels, Kubernetes Ingress, Gateway API and CRDs, Consul, Nomad, ECS and files.

Pros

  • Routes follow containers: add traefik.http.routers labels to a service and Traefik picks it up without a restart
  • Broadest provider list of the two: Docker, Swarm, Kubernetes Ingress, Gateway API, IngressRoute CRDs, ingress-nginx annotations, Consul, Nomad, ECS, etcd, Redis and more
  • DNS-01 works out of the box with lego's provider list, so wildcard certificates need no custom build
  • 24 open-source HTTP middlewares, including ForwardAuth, RateLimit, CircuitBreaker, Retry and IPAllowList
  • TCP routers with HostSNI rules and TLS passthrough, plus UDP routing, in the core binary
  • Two maintained lines: v3.7.16 and v2.11.60 both shipped on 20 Oct 2026

Cons

  • Not a web server: no built-in static file serving or FastCGI, so a site usually needs a separate container behind it
  • One DNS provider per certificate resolver, and the ACME docs say several instances with Let's Encrypt is not possible without cert-manager or Traefik Enterprise
  • OIDC, JWT, LDAP, OPA, WAF and distributed rate limiting are Traefik Hub features, not open source
  • The usual Docker setup mounts the Docker socket into the proxy, and api.insecure must not be used in production
  • Plugins are still marked experimental in the v3.7 docs

Best For

Docker Compose, Swarm and Kubernetes setups where services are added often and routing, TLS and middlewares should live next to each service in Git.

Config model: a Caddyfile versus labels everywhere

Caddy starts from a file. A site block with a hostname and a reverse_proxy line is a complete, HTTPS-enabled proxy. Under the hood the Caddyfile is converted to JSON, Caddy's native format, and the admin API on localhost:2019 lets you POST a whole new config to /load or change one path under /config. Reloads are zero-downtime, and if the new config fails, the old one is rolled back. You can treat Caddy as a static config you edit by hand or as a server you program. Traefik starts from providers. Its install configuration names the providers and entrypoints, and the routing configuration arrives from Docker labels, Kubernetes resources, Consul, Nomad, ECS, key-value stores or files. In Compose you write labels such as traefik.http.routers.app.rule=Host(`app.example.com`) on each service, and Traefik updates routes when it sees a change. There is no write API: the dashboard and API show what is running, but the source of truth is wherever your labels or manifests live. In practice, Caddy is easier to read as one file and Traefik is easier to scale as many small declarations spread across services. Caddy can mimic the label model with the third-party caddy-docker-proxy plugin, which turns labels into an in-memory Caddyfile and reloads on changes.

Certificates: defaults, DNS challenges and wildcards

Caddy's best-known feature is that HTTPS is on unless you turn it off. Public hostnames get certificates from Let's Encrypt, and if that fails Caddy tries ZeroSSL; IP addresses and internal names get certificates from a local CA Caddy creates. HTTP-01 and TLS-ALPN-01 are enabled by default. Instances sharing the same storage coordinate as a cluster, and On-Demand TLS can fetch a certificate during the first handshake for a domain you did not know about in advance, as long as you restrict it with an ask endpoint. The catch is DNS-01. Caddy's tls docs say the dns option uses a provider plugin that must be plugged in from the caddy-dns repositories, and Let's Encrypt needs DNS-01 for wildcards. That means building Caddy with xcaddy, using the :builder Docker image, or a custom build from the download page. Traefik needs a certificate resolver configured before any router gets HTTPS, but DNS-01 is built in through lego's provider list. Its own docs list two limits: one DNS provider per resolver, and no way to run several Traefik instances with Let's Encrypt, so HA needs cert-manager or the commercial Traefik Enterprise.

Web server versus edge router

Caddy is a web server that also proxies. file_server, php_fastcgi, templates, encode, request_body and intercept are standard directives, so one Caddy container can serve a static site, front a PHP-FPM pool and proxy an API. Its reverse_proxy supports twelve load-balancing policies, active and passive health checks, SRV and A/AAAA dynamic upstreams, retries and header rewriting, and handle_response for intercepting backend responses. Traefik is a router only. Its maintainers' standing answer is that it is a reverse proxy, not a web server: there is no built-in file server or FastCGI, so a static site needs its own nginx or Caddy container, or a third-party catalog plugin such as Statiq. In exchange, its open-source middlewares cover what proxies usually need: BasicAuth, DigestAuth, ForwardAuth for Authentik or Authelia, RateLimit, InFlightReq, CircuitBreaker, Retry, Headers, Compress and path rewrites. Raw TCP routing by HostSNI with TLS passthrough is in the core. In Caddy, rate limiting and layer-4 proxying come from plugins. caddy-ratelimit and caddy-l4 are both maintained, but caddy-l4's README calls itself experimental, warns of breaking changes, and notes it is not an official Caddy organisation repository. Treat those as dependencies you upgrade deliberately.

Kubernetes, extensions and upgrades

For Kubernetes the gap is wide. Traefik reads Ingress, the Gateway API, its own IngressRoute CRDs, Knative, and even ingress-nginx annotations through a dedicated provider, which matters for teams moving off ingress-nginx. Caddy's ingress controller under caddyserver/ingress has a Helm chart but its GitHub description still says WIP, so most Caddy users in clusters run it as an ordinary workload behind another ingress. Extensions work differently. Caddy plugins are Go modules compiled into the binary, so adding one means a rebuild, and caddy upgrade re-downloads a build with the same plugins. Traefik loads plugins from its catalog or a local directory at startup, but the v3.7 docs still label the feature experimental. Both projects ship often. Caddy 2.11.6 (1 Oct 2026) added slowloris idle timeouts and other security hardening with listed breaking changes; 2.11.7 followed two days later to fix a crash when proxying over HTTP/2 and SSE streams cut off at 60 seconds. Traefik patched v3.7 and v2.11 on 15 and 20 Oct 2026. Pin versions in Compose and read release notes before bumping either.

Verdict

Choose Caddy if you run one or a few servers, serve static files or PHP alongside your proxies, want HTTPS with no ACME config at all, or need certificates for customer domains through On-Demand TLS. Its config stays short and its admin API makes changes live. Choose Traefik if your routing is driven by containers or a cluster: Docker labels, Swarm or Kubernetes Ingress and Gateway API are first-class, DNS-01 wildcards work without a custom build, and rate limiting and TCP/UDP routing are in the core. If you would need three or more Caddy plugins (DNS provider, docker-proxy, ratelimit) to match your setup, that is the signal to use Traefik. If you would need a second container just to serve files, that is the signal to use Caddy.

All Comparisons

Caddy vs Traefik — FAQ

Common questions answered from the comparison above

Is Caddy easier than Traefik?

For a single server, yes. A Caddyfile with a hostname and a reverse_proxy line gives you HTTPS with no ACME settings. Traefik asks you to understand entrypoints, routers, services, middlewares and certificate resolvers first.

Can Caddy auto-discover Docker containers like Traefik?

Not on its own. The third-party caddy-docker-proxy plugin reads container labels, generates a Caddyfile in memory and reloads Caddy when containers change. Traefik does this natively with its Docker provider.

Does Caddy support wildcard certificates?

Yes, but Let's Encrypt requires the DNS challenge for wildcards, and Caddy's DNS challenge needs a provider module from the caddy-dns repositories, so you need a custom build. Traefik includes DNS providers through lego.

Can Traefik serve static files?

Not out of the box. Traefik routes and load-balances traffic but has no built-in file server or FastCGI support; third-party catalog plugins such as Statiq exist. Put an nginx or Caddy container behind it for static sites, or use Caddy for both jobs.

Which is better for Kubernetes?

Traefik. It supports Kubernetes Ingress, the Gateway API, IngressRoute CRDs and an ingress-nginx compatible provider. Caddy's ingress controller exists but is still described as work in progress.

Are Caddy and Traefik free?

Both are open source and free to self-host: Caddy under Apache-2.0, Traefik under MIT. Traefik Labs sells Traefik Hub and Enterprise, which add OIDC, JWT, WAF and distributed Let's Encrypt.

Get the next comparison by email

One email a week: new and trending developer tools, fresh comparisons, and what shipped. Unsubscribe in one click.