Understanding HAProxy Server Weight Configuration: Traffic Distribution and Calculation


3 views

Server weights in HAProxy only affect load balancing within their immediate backend. Each backend maintains its own isolated weight calculation. For example:

backend app1
    server s1 192.168.1.1:80 weight 50
    server s2 192.168.1.2:80 weight 30

backend app2
    server s3 192.168.1.3:80 weight 100
    server s4 192.168.1.4:80 weight 100

In this configuration, weights in app1 won't influence traffic distribution in app2.

Setting identical weights produces identical behavior to having no weights specified. HAProxy defaults to equal distribution when weights match:

backend example
    server s1 10.0.0.1:80 weight 1
    server s2 10.0.0.2:80 weight 1
    # Equivalent to:
    # server s1 10.0.0.1:80
    # server s2 10.0.0.2:80

To determine traffic distribution:

  1. Sum all weights: 100 + 100 + 90 + 90 = 380
  2. Calculate each server's share:
server web1: 100/380 = ~26.32%
server web2: 100/380 = ~26.32% 
server web3: 90/380 = ~23.68%
server web4: 90/380 = ~23.68%

Common weighting scenarios with expected traffic distribution:

# Case 1: Gradual capacity increase
server new1 10.1.1.1:80 weight 10  # ~9%
server old1 10.1.1.2:80 weight 100 # ~91%

# Case 2: Maintenance mode
server primary 10.2.2.1:80 weight 100
server standby 10.2.2.2:80 weight 1  # ~1% traffic

Enable runtime API for weight changes without restart:

global
    stats socket /var/run/haproxy.sock mode 660 level admin

# Then execute:
echo "set server backend/web3 weight 80" | socat stdio /var/run/haproxy.sock

html

In HAProxy, server weights exclusively influence traffic distribution within their assigned backend. This means weight adjustments won't affect other backends or frontend configurations. The weighting system operates as a relative distribution mechanism where higher-weighted servers receive proportionally more requests.

When configuring identical weights for all servers (e.g., weight 100 for each):

backend web_servers
    server web1 10.10.10.10 weight 100
    server web2 10.10.10.11 weight 100
    server web3 10.10.10.12 weight 100

This behaves identically to having no weights specified, resulting in perfect round-robin distribution. The weight system defaults to 1 when unspecified, making equal explicit weights functionally equivalent to omitted weights.

To determine exact traffic percentages when weights differ:

  1. Sum all server weights (100 + 100 + 90 + 90 = 380)
  2. Divide individual weight by total weight:
web1: 100/380 = 26.32%
web2: 100/380 = 26.32%  
web3: 90/380 = 23.68%
web4: 90/380 = 23.68%

Case 1: Gradual server retirement

backend phased_retirement
    server primary1 10.10.10.10 weight 100  # Active
    server primary2 10.10.10.11 weight 100  # Active
    server legacy1 10.10.10.12 weight 25    # Being phased out

Case 2: Hardware performance variance

backend mixed_hardware  
    server vm_small 10.10.10.10 weight 50   # 2vCPU
    server vm_medium 10.10.10.11 weight 75  # 4vCPU
    server vm_large 10.10.10.12 weight 100  # 8vCPU

For runtime modifications without restart:

# Check current weights:
echo "show servers state" | socat stdio /var/run/haproxy.sock

# Update weight dynamically:
echo "set server backend_name/server_name weight 200" | socat stdio /var/run/haproxy.sock
  • Using weights with balance source (weights don't affect hash-based balancing)
  • Setting extreme values (1 vs 10000) causing precision issues
  • Forgetting to adjust health check thresholds when changing weights significantly

HAProxy automatically reduces effective weight for unhealthy servers. Example behavior:

backend monitored
    server s1 10.10.10.10 weight 100 check inter 5s
    server s2 10.10.10.11 weight 100 check inter 5s
    # If s1 fails 2/3 checks, its effective weight becomes 33