How to Implement Rate Limiting and Circuit Breakers in Traefik: A Complete Guide
Traefik provides native middlewares for rate limiting and circuit breaking that protect backend services from traffic spikes and cascading failures through configurable token-bucket algorithms and failure threshold expressions.
Traefik, the cloud-native edge router, includes built-in middlewares for implementing rate limiting and circuit breakers to safeguard your microservices architecture. According to the traefik/traefik source code, these features leverage efficient in-memory algorithms and external libraries like github.com/sony/gobreaker to provide robust traffic management without requiring external dependencies.
Understanding Traefik's Rate Limiting Middleware
Traefik's rate limiting middleware controls traffic volume using a token-bucket algorithm that tracks request counts per source identifier (IP address, host header, or custom header).
Token-Bucket Algorithm and Source Implementation
The core implementation resides in pkg/middlewares/ratelimiter/rate_limiter.go, which instantiates either an in-memory or distributed limiter based on configuration. The in-memory implementation in pkg/middlewares/ratelimiter/in_memory_limiter.go uses a concurrent map to store per-source token buckets with configurable TTL eviction.
For each request, the middleware calls Allow(ctx, source), which returns either a nil delay (immediate forwarding) or a sleep duration that the router respects before forwarding. When requests exceed the configured burst capacity and maximum delay, Traefik returns HTTP 429 Too Many Requests.
Configuration Options
The rate limiter accepts the following key parameters:
- average: Requests per second allowed (sustained rate)
- burst: Maximum number of requests allowed in a burst
- delay: Maximum delay duration before rejecting requests (optional)
- sourceCriterion: Defines how to identify unique clients (IP, Host, or custom headers)
- distributed: Enables cluster-wide rate limiting using Redis or Consul
Distributed Rate Limiting for Cluster Deployments
For multi-instance Traefik deployments, the distributed rate limiter stores counters in an external key-value store rather than local memory. When distributed.provider is set to redis or consul, the middleware delegates counting to the distributedRatelimit package while maintaining the same token-bucket algorithm.
Implementing Circuit Breakers in Traefik
The circuit breaker middleware monitors request health metrics and temporarily blocks traffic to failing services to prevent cascading failures.
Expression-Based Thresholds and State Machine
The implementation in pkg/middlewares/circuitbreaker/circuit_breaker.go leverages the github.com/sony/gobreaker library and github.com/Knetic/govaluate for expression parsing. The middleware evaluates user-defined expressions against request metrics:
- Latency: Response time thresholds (e.g.,
Latency > 500ms) - ResponseCode: HTTP status code patterns (e.g.,
ResponseCode >= 500) - NetworkErrorRatio: Percentage of connection failures
The circuit breaker maintains three states:
- Closed: Requests pass through normally while failures are counted
- Open: Requests immediately fail with HTTP 503 until the timeout expires
- Half-Open: Limited trial requests probe service recovery
Fallback Handling
When the circuit breaker trips (enters Open state), Traefik can return a static HTTP 503 response or forward requests to a configured fallback service. The fallback parameter specifies an alternative service name that receives traffic while the primary service recovers.
Practical Configuration Examples
File Provider (YAML) Configuration
Static configuration (traefik.yml):
entryPoints:
web:
address: ":80"
providers:
file:
filename: "/etc/traefik/dynamic.yml"
Dynamic configuration (dynamic.yml):
http:
middlewares:
my-ratelimit:
rateLimit:
average: 10
burst: 20
responseHeaders: true
delay: "2s"
my-circuitbreaker:
circuitBreaker:
expression: "Latency > 500ms"
fallback: "fallback-service"
routers:
my-router:
rule: "Host(`example.com`)"
entryPoints: ["web"]
service: my-service
middlewares: ["my-ratelimit", "my-circuitbreaker"]
services:
my-service:
loadBalancer:
servers:
- url: "http://backend:8080"
fallback-service:
loadBalancer:
servers:
- url: "http://fallback:8080"
Docker Compose Labels
version: "3.8"
services:
traefik:
image: traefik:v2.11
command:
- "--api.insecure=true"
- "--providers.docker=true"
- "--entrypoints.web.address=:80"
ports:
- "80:80"
- "8080:8080"
volumes:
- "/var/run/docker.sock:/var/run/docker.sock"
app:
image: myapp:latest
labels:
- "traefik.http.routers.app.rule=Host(`app.local`)"
- "traefik.http.routers.app.entrypoints=web"
- "traefik.http.routers.app.middlewares=ratelimit@docker,circuitbreaker@docker"
Distributed Rate Limiting with Redis
http:
middlewares:
redis-ratelimit:
rateLimit:
average: 20
burst: 40
distributed:
provider: "redis"
address: "redis:6379"
password: ""
tls: false
Key Source Files and Implementation Details
| Feature | File | Description |
|---|---|---|
| Rate‑limit core | pkg/middlewares/ratelimiter/rate_limiter.go |
Middleware entry point, config parsing, request hook |
| In‑memory limiter | pkg/middlewares/ratelimiter/in_memory_limiter.go |
Token‑bucket implementation with TTL eviction |
| Circuit‑breaker core | pkg/middlewares/circuitbreaker/circuit_breaker.go |
Expression parsing, gobreaker integration, fallback handling |
| Kubernetes CRD | pkg/provider/kubernetes/crd/generated/applyconfiguration/traefikio/v1alpha1/circuitbreaker.go |
Kubernetes CRD schema definitions |
Summary
-
Rate limiting in Traefik uses a token-bucket algorithm implemented in
pkg/middlewares/ratelimiter/rate_limiter.goto control request rates per source, with optional distributed storage via Redis or Consul for multi-instance deployments. -
Circuit breakers leverage the
github.com/sony/gobreakerlibrary inpkg/middlewares/circuitbreaker/circuit_breaker.goto monitor latency and error rates, automatically tripping to prevent cascading failures when thresholds are exceeded. -
Both middlewares integrate seamlessly with Traefik's dynamic configuration providers, supporting YAML file providers, Docker labels, and Kubernetes CRDs for flexible deployment across containerized environments.
Frequently Asked Questions
How does Traefik's rate limiter handle burst traffic?
Traefik's rate limiter implements a token-bucket algorithm that allows temporary traffic bursts up to the configured burst value while maintaining the sustained average rate. When the burst capacity is exceeded and the delay parameter is set, Traefik queues requests for the specified duration before returning HTTP 429; otherwise, it rejects excess requests immediately.
What expression syntax does the Traefik circuit breaker use?
The circuit breaker in Traefik uses expression syntax parsed by github.com/Knetic/govaluate, allowing you to define thresholds using metrics like Latency > 500ms, ResponseCode >= 500, or NetworkErrorRatio > 0.5. These expressions determine when the circuit transitions from Closed to Open state based on real-time request monitoring.
Can I use rate limiting across multiple Traefik instances?
Yes, Traefik supports distributed rate limiting by configuring the distributed option with a key-value store provider such as Redis or Consul. This stores token-bucket counters externally in pkg/middlewares/ratelimiter/rate_limiter.go, ensuring consistent rate limits across all Traefik replicas in a cluster.
What happens when a circuit breaker trips in Traefik?
When the circuit breaker trips (enters the Open state), Traefik immediately returns HTTP 503 Service Unavailable for incoming requests or forwards them to a configured fallback service if specified. After the timeout period expires, the breaker enters Half-Open state to test if the backend has recovered before fully closing the circuit again.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →