Caddy vs Envoy: Which Proxy to Self-Host?
Quick Verdict
Caddy is the right choice for self-hosting. Two-line configs, automatic HTTPS, and a clean plugin ecosystem. Envoy is a service mesh proxy for cloud-native infrastructure — its verbose typed YAML configuration and enterprise feature set are mismatched for homelab or VPS setups.
Overview
Caddy is a modern web server and reverse proxy that provides automatic HTTPS with zero configuration. Its Caddyfile format is the simplest proxy config syntax available. Current version: 2.10.2.
Envoy is a high-performance edge and service proxy, originally built at Lyft and now a CNCF graduated project. It’s the data plane for Istio and other service meshes. Current version: v1.37.0.
Feature Comparison
| Feature | Caddy 2.10 | Envoy v1.37 |
|---|---|---|
| Automatic HTTPS | Yes (zero config) | No |
| Config format | Caddyfile (2 lines per site) | Typed YAML (30+ lines per route) |
| JSON API | Yes (hot reload) | xDS API (complex) |
| Static file serving | Yes | No |
| gRPC proxying | Yes | Native first-class |
| Circuit breaking | No | Yes |
| Distributed tracing | No | Yes (Zipkin, Jaeger) |
| WebAssembly plugins | No | Yes |
| HTTP/3 | Experimental | Yes |
| Load balancing | Yes (multiple policies) | Advanced (12+ algorithms) |
| Health checks | Active + passive | Advanced |
| Plugin ecosystem | Yes (xcaddy) | Wasm + filter chains |
| Learning curve | Low | Very high |
| Written in | Go | C++ |
Installation Complexity
Caddy
services:
caddy:
image: caddy:2.10.2-alpine
ports:
- "80:80"
- "443:443"
volumes:
- ./Caddyfile:/etc/caddy/Caddyfile:ro
- caddy-data:/data
restart: unless-stopped
Caddyfile:
app.example.com {
reverse_proxy app:8080
}
HTTPS is automatic. Done.
Envoy
A simple HTTP proxy requires 30+ lines of typed YAML with @type annotations, filter chain definitions, cluster configurations, and endpoint specifications. SSL requires SDS setup or manual certificate management.
Winner: Caddy. Not comparable in terms of setup effort.
Performance and Resource Usage
| Metric | Caddy | Envoy |
|---|---|---|
| Idle RAM | ~30-50 MB | ~30-50 MB |
| Requests/sec | ~40,000 | ~80,000+ |
| P99 latency | ~0.5ms | ~0.3ms |
| Binary size | ~40 MB | ~60 MB |
Envoy is faster due to its C++ implementation. For self-hosting loads, both perform identically.
Use Cases
Choose Caddy If…
- You’re self-hosting Docker containers and want automatic HTTPS
- You want the simplest possible configuration syntax
- You need a web server and reverse proxy combined
- You want a plugin ecosystem without C++ compilation
- You want config-as-code that’s human-readable
Choose Envoy If…
- You’re building on Kubernetes with a service mesh
- You need gRPC-native proxying
- You need circuit breaking and distributed tracing
- You need xDS dynamic configuration
- You’re running large-scale microservice infrastructure
Final Verdict
Caddy for self-hosting, Envoy for cloud-native infrastructure. Caddy gives you automatic HTTPS, a two-line-per-service config, and a clean plugin system. Envoy gives you a service mesh data plane with observability features most self-hosters will never need.
Frequently Asked Questions
Is Envoy faster than Caddy?
In benchmarks, yes. In real self-hosting use (under 1,000 concurrent connections), the difference is undetectable.
Can Caddy replace Envoy in Kubernetes?
Not directly. Caddy doesn’t integrate with Kubernetes’ control plane the way Envoy does (via xDS). There is a Caddy ingress controller for Kubernetes, but it’s not as mature as Envoy-based alternatives like Contour or Envoy Gateway.
Does Caddy support gRPC?
Yes, but as a passthrough proxy rather than with Envoy’s native gRPC-specific features (health checking, load balancing per-stream, etc.).
Related
Get self-hosting tips in your inbox
New guides, comparisons, and setup tutorials — delivered weekly. No spam.