Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/traefik/traefik/llms.txt

Use this file to discover all available pages before exploring further.

Services

Services define how to reach backend servers and handle load balancing.

What is a Service?

A service configures how Traefik forwards requests to your backend servers. Each service defines:
  • Servers: One or more backend server addresses
  • Load Balancing: Algorithm to distribute requests
  • Health Checks: Monitoring to remove unhealthy servers
  • Sticky Sessions: Route clients to the same server

HTTP Services

HTTP services use the loadBalancer configuration to distribute requests across backend servers.

Basic Service Configuration

http:
  services:
    my-service:
      loadBalancer:
        servers:
          - url: "http://10.0.1.10:8080"
          - url: "http://10.0.1.11:8080"
          - url: "http://10.0.1.12:8080"

Service Configuration Options

servers
array
required
List of backend server URLs.
servers:
  - url: "http://10.0.1.10:8080"
  - url: "http://10.0.1.11:8080"
strategy
string
Load balancing algorithm: wrr (default), p2c, or hrw.
strategy: "p2c"
healthCheck
object
Health check configuration to monitor server availability.
healthCheck:
  path: /health
  interval: "10s"
sticky
object
Sticky session configuration using cookies.
sticky:
  cookie:
    name: "lb_cookie"
passHostHeader
boolean
Forward the Host header to backend servers (default: true).
passHostHeader: true

Load Balancing Algorithms

Traefik supports three load balancing strategies with different characteristics.

Weighted Round Robin (WRR)

Default algorithm using Earliest Deadline First (EDF) scheduling. Implemented in pkg/server/service/loadbalancer/wrr/wrr.go.
Distribute requests evenly across all servers:
http:
  services:
    api-service:
      loadBalancer:
        servers:
          - url: "http://10.0.1.10:8080"
          - url: "http://10.0.1.11:8080"
          - url: "http://10.0.1.12:8080"
Each server receives ~33% of traffic.
WRR uses O(log n) selection time with a heap-based implementation for efficient server selection.

Power of Two Choices (P2C)

Selects two random servers and chooses the one with fewer active requests. Implemented in pkg/server/service/loadbalancer/p2c/p2c.go.
http:
  services:
    api-service:
      loadBalancer:
        strategy: "p2c"
        servers:
          - url: "http://10.0.1.10:8080"
          - url: "http://10.0.1.11:8080"
          - url: "http://10.0.1.12:8080"
When to use P2C:
  • High-concurrency applications
  • Servers with varying response times
  • Distributed deployments without central coordination
  • Better “herd behavior” than least connections
P2C provides O(1) selection time by randomly sampling two servers instead of checking all servers.

Highest Random Weight (HRW)

Rendezvous hashing that routes clients consistently to the same server based on client IP. Implemented in pkg/server/service/loadbalancer/hrw/hrw.go.
http:
  services:
    api-service:
      loadBalancer:
        strategy: "hrw"
        servers:
          - url: "http://10.0.1.10:8080"
            weight: 2
          - url: "http://10.0.1.11:8080"
            weight: 1
When to use HRW:
  • Cache-heavy applications (consistent routing to same server)
  • Session affinity without sticky cookies
  • Minimal disruption when adding/removing servers
HRW uses client IP for routing. Requests from the same IP always go to the same backend (unless server is unhealthy).

Health Checks

Health checks automatically remove unhealthy servers from load balancing rotation.

Basic Health Check

http:
  services:
    api-service:
      loadBalancer:
        servers:
          - url: "http://10.0.1.10:8080"
          - url: "http://10.0.1.11:8080"
        healthCheck:
          path: /health
          interval: "10s"
          timeout: "3s"

Health Check Options

path
string
required
Health check endpoint path (relative URL).
path: /health
interval
duration
Frequency of health checks for healthy servers (default: 30s).
interval: "10s"
unhealthyInterval
duration
Frequency of health checks for unhealthy servers (default: same as interval).
unhealthyInterval: "5s"
timeout
duration
Maximum duration to wait for health check response (default: 5s).
timeout: "3s"
scheme
string
Override URL scheme for health checks (http or https).
scheme: https
hostname
string
Hostname to use in Host header for health checks.
hostname: "health.example.com"
port
integer
Override port for health check endpoint.
port: 9000
method
string
HTTP method for health checks (default: GET).
method: "HEAD"
status
integer
Expected HTTP status code (default: accept any 2xx or 3xx).
status: 200
headers
object
Custom headers to send with health check requests.
headers:
  Authorization: "Bearer token123"
  X-Custom-Header: "value"
followRedirects
boolean
Follow redirects during health checks (default: true).
followRedirects: false
mode
string
Health check mode: http (default) or grpc.
mode: grpc

Advanced Health Check Examples

Use dedicated health check port and path:
http:
  services:
    api-service:
      loadBalancer:
        servers:
          - url: "http://10.0.1.10:8080"
        healthCheck:
          path: /actuator/health
          port: 9000
          scheme: http
          interval: "15s"
          timeout: "5s"
Send authentication headers with health checks:
http:
  services:
    secure-api:
      loadBalancer:
        servers:
          - url: "https://10.0.1.10:8443"
        healthCheck:
          path: /health
          headers:
            Authorization: "Bearer health-check-token"
            X-Health-Check: "true"
          interval: "10s"
Use gRPC health check protocol:
http:
  services:
    grpc-service:
      loadBalancer:
        servers:
          - url: "h2c://10.0.1.10:50051"
        healthCheck:
          path: /
          mode: grpc
          interval: "10s"
          timeout: "3s"
Traefik uses gRPC health check v1 protocol and expects SERVING status.
Check unhealthy servers more frequently:
http:
  services:
    api-service:
      loadBalancer:
        servers:
          - url: "http://10.0.1.10:8080"
        healthCheck:
          path: /health
          interval: "30s"          # Healthy servers checked every 30s
          unhealthyInterval: "5s"  # Unhealthy servers checked every 5s
          timeout: "3s"
Healthy servers that become unhealthy are automatically removed from rotation. Once they recover (returning 2xx-3xx status), they’re added back automatically.

Sticky Sessions

Sticky sessions route requests from the same client to the same backend server using cookies.

Basic Sticky Sessions

http:
  services:
    app-service:
      loadBalancer:
        servers:
          - url: "http://10.0.1.10:8080"
          - url: "http://10.0.1.11:8080"
        sticky:
          cookie: {}
sticky:
  cookie: {}  # Uses auto-generated name
name
string
Cookie name. Default is SHA1 hash abbreviation (e.g., _1d52e).
name: "server_id"
secure
boolean
Set Secure flag (HTTPS only). Default: false.
secure: true
httpOnly
boolean
Set HttpOnly flag (no JavaScript access). Default: false.
httpOnly: true
sameSite
string
SameSite attribute: none, lax, strict, or empty. Default: empty.
sameSite: "lax"
maxAge
integer
Cookie expiration in seconds. Default: 0 (session cookie). Negative values create expired cookies.
maxAge: 86400  # 24 hours
domain
string
Cookie domain for subdomain sharing.
domain: ".example.com"  # Shared across subdomains
If a server becomes unhealthy, requests are forwarded to a new healthy server and the cookie is updated.

Server Options

Individual server configuration options:

Server Weight

http:
  services:
    api-service:
      loadBalancer:
        servers:
          - url: "http://10.0.1.10:8080"
            weight: 3  # High capacity server
          - url: "http://10.0.1.11:8080"
            weight: 1  # Lower capacity server

Preserve Path

Preserve URL path when forwarding to backends:
http:
  services:
    api-service:
      loadBalancer:
        servers:
          - url: "http://10.0.1.10:8080/api"
            preservePath: true
preservePath is ignored when health checks are configured.

TCP Services

TCP services forward raw TCP connections to backend servers.
tcp:
  services:
    database-service:
      loadBalancer:
        servers:
          - address: "10.0.1.20:5432"
          - address: "10.0.1.21:5432"
        proxyProtocol:
          version: 2
TCP services use address (host:port) instead of url. Load balancing algorithm is always round-robin.

UDP Services

UDP services forward UDP packets to backend servers.
udp:
  services:
    dns-service:
      loadBalancer:
        servers:
          - address: "10.0.1.30:53"
          - address: "10.0.1.31:53"

Weighted Services

Combine multiple services with weighted traffic distribution:
http:
  services:
    # Combined weighted service
    canary-deployment:
      weighted:
        services:
          - name: stable-v1
            weight: 90  # 90% traffic
          - name: canary-v2
            weight: 10  # 10% traffic
    
    # Individual services
    stable-v1:
      loadBalancer:
        servers:
          - url: "http://10.0.1.10:8080"
    
    canary-v2:
      loadBalancer:
        servers:
          - url: "http://10.0.2.10:8080"

Mirroring Services

Mirror traffic to another service for testing:
http:
  services:
    production-with-mirror:
      mirroring:
        service: production-service
        maxBodySize: 1048576  # 1MB
        mirrors:
          - name: test-service
            percent: 10  # Mirror 10% of traffic
    
    production-service:
      loadBalancer:
        servers:
          - url: "http://10.0.1.10:8080"
    
    test-service:
      loadBalancer:
        servers:
          - url: "http://10.0.2.10:8080"
Mirrored requests are fire-and-forget. Responses from mirrored services are ignored.

Real-World Examples

Complete service with health checks and sticky sessions:
http:
  services:
    api-production:
      loadBalancer:
        strategy: "p2c"
        servers:
          - url: "http://10.0.1.10:8080"
          - url: "http://10.0.1.11:8080"
          - url: "http://10.0.1.12:8080"
        healthCheck:
          path: /health
          interval: "10s"
          unhealthyInterval: "5s"
          timeout: "3s"
          headers:
            X-Health-Check: "true"
        sticky:
          cookie:
            name: "api_session"
            secure: true
            httpOnly: true
            sameSite: "lax"
Route traffic between two service versions:
http:
  services:
    blue-green:
      weighted:
        services:
          - name: blue-v1
            weight: 100  # All traffic to blue
          - name: green-v2
            weight: 0    # No traffic to green yet
    
    blue-v1:
      loadBalancer:
        servers:
          - url: "http://10.0.1.10:8080"
        healthCheck:
          path: /health
          interval: "10s"
    
    green-v2:
      loadBalancer:
        servers:
          - url: "http://10.0.2.10:8080"
        healthCheck:
          path: /health
          interval: "10s"
Gradually shift traffic by adjusting weights: 90/10, 50/50, 0/100.
Multiple services with different configurations:
http:
  services:
    auth-service:
      loadBalancer:
        strategy: "hrw"  # Consistent hashing for sessions
        servers:
          - url: "http://10.0.1.10:8080"
          - url: "http://10.0.1.11:8080"
        healthCheck:
          path: /health
          interval: "10s"
    
    api-service:
      loadBalancer:
        strategy: "p2c"  # Best for high concurrency
        servers:
          - url: "http://10.0.2.10:8080"
          - url: "http://10.0.2.11:8080"
          - url: "http://10.0.2.12:8080"
        healthCheck:
          path: /health
          interval: "5s"
    
    database-proxy:
      loadBalancer:
        servers:
          - url: "http://10.0.3.10:5432"
          - url: "http://10.0.3.11:5432"
            weight: 2  # Read replica
        sticky:
          cookie:
            name: "db_connection"

Next Steps

Configure EntryPoints

Set up network entry points for incoming traffic

Create Routers

Define routing rules to connect requests to services