Skip to main content

Load-Balancing Algorithms

Traefik Hub supports multiple load-balancing algorithms for distributing traffic across backend servers. Each algorithm suits different workload patterns — from basic even distribution to latency-aware routing and consistent hashing. This page covers what each algorithm does, when to use it, and how to configure it.

Weighted Round Robin (WRR)

WRR is the default algorithm. It distributes requests evenly across all servers in rotation, respecting server weights. Under the hood, it uses Earliest Deadline First (EDF) scheduling to achieve weighted distribution.

Assign a weight to each server to control how much traffic it receives relative to the others. A server with weight 3 receives three times the traffic of a server with weight 1.

apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: my-app
namespace: apps
spec:
entryPoints:
- websecure
routes:
- match: Host(`app.example.com`)
kind: Rule
services:
- name: my-app
port: 80
strategy: wrr
tls: {}

When to use: Default choice for most workloads. Use weighted distribution during migrations to shift traffic gradually between backends.

Power of Two Choices (P2C)

P2C selects two servers at random and routes the request to the one with the fewest active connections. This is particularly effective in environments where backend servers have varying response times, as it naturally adapts to server load without requiring global state.

apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: my-app
namespace: apps
spec:
entryPoints:
- websecure
routes:
- match: Host(`app.example.com`)
kind: Rule
services:
- name: my-app
port: 80
strategy: p2c
tls: {}

When to use: Auto-scaling environments and workloads with variable connection lifetimes, such as WebSocket applications. P2C balances connections without the overhead of tracking global state.

Highest Random Weight (HRW)

HRW implements consistent hashing based on the client's source IP address. For each request, it computes a score for every available backend using a hash of the client IP combined with the backend identifier, then routes to the highest-scoring backend.

This provides implicit session affinity — requests from the same client consistently route to the same server — without requiring cookies.

apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: my-app
namespace: apps
spec:
entryPoints:
- websecure
routes:
- match: Host(`app.example.com`)
kind: Rule
services:
- name: my-app
port: 80
strategy: hrw
tls: {}

When to use: API clients, mobile apps, or sessionless connections where cookie-based stickiness isn't an option but you still need consistent routing. Also useful when backend servers maintain local caches that benefit from client affinity.

Least-Time

Least-Time selects servers based on the lowest average response time (Time To First Byte), combined with the fewest active connections, weighted by server capacity. The scoring formula is:

score = (avg_response_time × (1 + active_connections)) / weight

Ties are broken using WRR with EDF scheduling.

apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: my-app
namespace: apps
spec:
entryPoints:
- websecure
routes:
- match: Host(`app.example.com`)
kind: Rule
services:
- name: my-app
port: 80
strategy: leasttime
tls: {}

When to use: Latency-sensitive workloads where you want the gateway to automatically favor faster backends. Combines well with weighted distribution for mixed-capacity environments.

Sticky Sessions

Sticky sessions ensure that once a client is routed to a specific server, subsequent requests from the same client go to the same server. Traefik sets a Set-Cookie header on the initial response, and the client returns it on subsequent requests.

apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: my-app
namespace: apps
spec:
entryPoints:
- websecure
routes:
- match: Host(`app.example.com`)
kind: Rule
services:
- name: my-app
port: 80
sticky:
cookie:
name: my_app_sticky
secure: true
httpOnly: true
sameSite: strict
tls: {}

Configuration Options

FieldDescriptionDefaultRequired
nameCookie name.SHA1 abbreviation (e.g., _1d52e)No
secureSets the Secure flag.falseNo
httpOnlySets the HttpOnly flag.falseNo
sameSiteSets the SameSite attribute (strict, lax, none).-No
maxAgeCookie lifetime in seconds. 0 = session cookie, negative = expire immediately.0No
domainCookie domain scope.-No
pathCookie path scope.-No
note

If a sticky server becomes unhealthy, Traefik redirects traffic to a new healthy server and updates the cookie accordingly.

When to use: Stateful applications where the backend maintains session data locally. Combine with any algorithm — stickiness overrides the algorithm for returning clients. Note that combining sticky sessions with HRW is redundant: HRW already provides implicit stickiness via consistent hashing on the client IP, so both mechanisms will route to the same server anyway.

Health Checks

Health checks remove unhealthy servers from the load-balancing pool and re-add them when they recover. Traefik supports both active and passive checks.

Active Health Checks

Traefik periodically sends requests to a health endpoint on each server:

apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: my-app
namespace: apps
spec:
entryPoints:
- websecure
routes:
- match: Host(`app.example.com`)
kind: Rule
services:
- name: my-app
port: 80
healthCheck:
path: /health
interval: 10s
timeout: 3s
tls: {}

Configuration Options

FieldDescriptionDefaultRequired
pathHealth check endpoint.-Yes
intervalCheck frequency for healthy targets.30sNo
unhealthyIntervalCheck frequency for unhealthy targets.Same as intervalNo
timeoutMaximum wait for a response.5sNo
statusExpected HTTP status code.2XX-3XXNo
modeSet to grpc for gRPC health check v1.-No
headersCustom headers to include in the check.-No
followRedirectsFollow HTTP redirects.trueNo

Passive Health Checks

Passive checks monitor real production traffic instead of sending synthetic requests:

apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: my-app
namespace: apps
spec:
entryPoints:
- websecure
routes:
- match: Host(`app.example.com`)
kind: Rule
services:
- name: my-app
port: 80
passiveHealthCheck:
failureWindow: 10s
maxFailedAttempts: 3
tls: {}

Configuration Options

FieldDescriptionDefaultRequired
failureWindowTime window for counting failures; also defines recovery duration.10sNo
maxFailedAttemptsConsecutive failures before marking unhealthy.1No
tip

Combine active and passive health checks for the best coverage. Passive checks catch degradation in real traffic immediately, while active checks detect servers that are down but not receiving traffic.

Choosing an Algorithm

AlgorithmAffinityAdapts to LoadScenarioWhy It Fits
WRR (default)NoNoIdentical servers, uniform requestsSimple, predictable, no overhead
WRR with weightsNoNoDifferent server types/performanceProportional to capacity
P2CNoYes (connections)Auto-scaling, variable connection lifetimesBalances connection count dynamically
HRWYes (IP-based)NoClient affinity for caching, stateful backendsConsistent client-to-server mapping
Least-TimeNoYes (latency + connections)Heterogeneous backends, latency-sensitiveOptimizes for actual performance

For cookie-based session affinity, add sticky sessions on top of any algorithm.

For service-level traffic management such as canary/blue-green deployments or traffic mirroring, see the related pages below.