Traefik vs HAProxy: Reverse Proxy Showdown
Quick Verdict
Traefik is the better choice for most self-hosters. It auto-discovers Docker containers via labels, handles Let’s Encrypt certificates automatically, and requires no config file editing when you add new services. HAProxy is the better choice if you need production-grade load balancing, TCP proxying, advanced health checks, or stick-table-based rate limiting — but that level of power is rarely needed in a homelab.
Overview
Traefik (v3.6) is a cloud-native edge router that watches Docker, Kubernetes, and other providers for service changes. When you deploy a new container with the right labels, Traefik automatically creates a route and provisions an SSL certificate. Configuration is split between a static config file (entry points, providers) and dynamic config (Docker labels on each service).
HAProxy (v3.3) is a high-performance TCP/HTTP load balancer used by GitHub, Reddit, and Stack Overflow. It is configured entirely through a single config file (haproxy.cfg) with no auto-discovery. HAProxy’s strength is its load balancing algorithms, health checks, stick tables, and TCP-level proxying capabilities.
Both are open source, high-performance, and written in different languages (Traefik in Go, HAProxy in C). They target different workflows: Traefik is container-native, HAProxy is infrastructure-native.
Feature Comparison
| Feature | Traefik (v3.6) | HAProxy (v3.3) |
|---|---|---|
| Auto service discovery | Yes — Docker, Swarm, K8s, Consul | No — manual config only |
| Configuration method | Docker labels + YAML static config | Single config file (haproxy.cfg) |
| Automatic HTTPS | Yes — Let’s Encrypt built-in | No — external ACME client needed |
| Load balancing algorithms | Round robin, weighted, sticky | Round robin, least connections, source, URI, random, power-of-two |
| Health checks | Yes — automatic | Yes — advanced (HTTP content checks, TCP, custom scripts) |
| TCP/UDP proxying | Yes | Yes — more mature, battle-tested |
| Stick tables (session persistence) | Basic — cookie-based | Advanced — IP, cookie, URL, custom keys with counters |
| Rate limiting | Via middleware | Native — stick tables with request rate tracking |
| Web dashboard | Yes — read-only | Yes — stats page with real-time metrics |
| HTTP/2 | Yes | Yes |
| HTTP/3 (QUIC) | Yes | Not yet (planned) |
| Middleware ecosystem | 30+ built-in | Limited — ACLs and http-request rules |
| Docker Swarm support | Yes — native | No |
| Kubernetes support | Yes — IngressRoute CRD | Yes — Kubernetes Ingress Controller (separate project) |
| Metrics | Prometheus, OpenTelemetry | Prometheus exporter, stats socket |
| Config reload | Hot reload (label changes detected) | Graceful reload via SIGHUP |
| License | MIT | GPL v2 (FOSS), HAProxy Technologies License (Enterprise) |
Installation Complexity
Traefik requires more initial setup than it first appears. You need a static config file defining entry points and certificate resolvers, then Docker labels on every service you want to proxy. But once set up, adding new services is trivial — just add labels to the container’s Compose file.
HAProxy has a steeper config learning curve. The haproxy.cfg file uses a custom syntax with global, defaults, frontend, and backend sections. Adding a new service means editing the config file and sending SIGHUP to reload. There is no auto-discovery. But the config format is well-documented and predictable.
For a homelab that changes frequently (adding/removing containers), Traefik’s auto-discovery saves significant time. For a stable setup that rarely changes, HAProxy’s explicit config is equally manageable.
Performance and Resource Usage
| Metric | Traefik | HAProxy |
|---|---|---|
| Idle RAM | ~80-120 MB | ~15-30 MB |
| Under load RAM | ~200-400 MB | ~50-100 MB |
| Latency overhead | Very low | Extremely low (C, event-driven) |
| Max concurrent connections | High | Very high (designed for 100K+ concurrent) |
| Docker image size | ~130 MB | ~100 MB |
HAProxy is significantly lighter and faster. Written in C with an event-driven architecture, it is designed for extreme concurrency. Traefik’s Go runtime and service discovery watchers consume more memory. For a homelab, this difference is negligible. For production load balancing at scale, HAProxy’s efficiency matters.
Community and Support
| Metric | Traefik | HAProxy |
|---|---|---|
| GitHub stars | 53K+ | 5K+ (lower because it predates GitHub) |
| First release | 2016 | 2001 |
| Documentation | Good, modern docs site | Excellent, comprehensive reference |
| Commercial support | Traefik Enterprise | HAProxy Technologies (Enterprise + ALOHA) |
| Community | Forums, Discord, Reddit | Mailing list, Discourse, IRC |
HAProxy has 15 years more history and is the foundation of internet infrastructure. Traefik has a larger GitHub presence because it is container-native and attracts the Docker/Kubernetes community. Both have strong commercial offerings.
Use Cases
Choose Traefik If…
- You run Docker containers and want automatic routing via labels
- You want built-in Let’s Encrypt without an external ACME client
- You deploy on Docker Swarm or Kubernetes
- You add and remove services frequently
- You want middleware (authentication, rate limiting, headers) configurable per-route via labels
- You prefer config-as-code where routing lives with the service definition
Choose HAProxy If…
- You need production-grade load balancing across multiple backend servers
- You proxy TCP traffic (databases, MQTT, game servers)
- You need advanced health checks (HTTP content matching, TCP checks, scripts)
- You need stick-table-based rate limiting and DDoS protection
- Maximum performance and minimal overhead are critical
- You run bare-metal or VM infrastructure without Docker
FAQ
Can HAProxy auto-discover Docker containers?
Not natively. There are third-party tools like docker-gen that can generate HAProxy configs from container labels, but this is not built-in and not as reliable as Traefik’s native provider.
Which handles more traffic?
HAProxy, by a significant margin. It is designed for 100K+ concurrent connections and is used by some of the largest websites. Traefik handles homelab and medium-scale traffic without issues but is not in the same class for extreme load.
Can I migrate from one to the other?
Routes do not transfer. Traefik uses Docker labels; HAProxy uses haproxy.cfg. You would rewrite your routing config in the target format. SSL certificates via Let’s Encrypt will be re-provisioned automatically by Traefik; HAProxy requires manual certificate management regardless.
Final Verdict
Traefik wins for self-hosting. Auto-discovery, built-in HTTPS, and Docker-native integration make it the practical choice for homelabs and small-scale deployments. Adding a new service is two Docker labels instead of editing a config file and reloading.
HAProxy wins in a different arena: production infrastructure, high-traffic load balancing, and TCP proxying. If you are running a cluster of web servers behind a load balancer, HAProxy is the industry standard. But most self-hosters are running a single server with 5-30 services, and Traefik handles that better.
Related
Get self-hosting tips in your inbox
New guides, comparisons, and setup tutorials — delivered weekly. No spam.