Cloudflare Docs
Load-Balancing
Visit Load Balancing on GitHub
Set theme to dark (⇧+D)

Get started

This guide is meant for organizations setting up their first load balancer. If you already have active load balancers, refer to Basic tasks for general help or Additional configurations for more advanced setups.


Prerequisites

  • Multiple servers, either physical or cloud-based.
  • Access to Load Balancing, available as an add-on for any type of account.
  • Load balancer hostname: The hostname for which the Cloudflare Load Balancer will manage traffic. The default hostname is the root hostname.

Step 1 — Create a monitor

A monitor issues health checks at regular intervals to evaluate the health of an origin pool . When a pool becomes unhealthy , your load balancer takes that pool out of the server rotation.
Create a monitor (dashboard)

Set up the monitor

You can create a monitor within the load balancer workflow or in the Monitors section of the dashboard:

  1. Go to Traffic > Load Balancing.

  2. Click Manage Monitors.

  3. Click Create.

  4. Add the following information:

    • Type: The protocol to use for health checks
      • Non-enterprise customers: Choose HTTP, HTTPS, or TCP.
      • Enterprise customers: Choose HTTP, HTTPS, TCP, UDP ICMP, ICMP Ping, or SMTP.
    • Path: The endpoint path to run health checks against
    • Port: The destination port for health checks
  5. For additional settings, select Advanced health check settings:

    • Interval:
      • By increasing the default, you can improve failover time, but you may also increase load on your servers.
      • Minimum time in seconds is 60 (Pro), 10 (Business), and 5 (Enterprise).
    • Timeout and Retries:
      • The health check will return unhealthy if it exceeds the duration specified in Timeout (and exceeds this duration more times than the specified number of Retries).
    • Expected Code(s): The expected HTTP response codes listed individually (200, 302) or as a range (2xx, 3xx).
    • Response Body:
      • Looks for a case-insensitive substring in the response body.
      • Make sure that the value is relatively static and within the first 100,000 KB of the HTML page.
    • Simulate Zone:
    • Follow Redirects:
      • Instead of reporting a 301 or 302 code as unhealthy, the health check follows redirects to the final endpoint.
    • Configure Request Header(s):
      • Useful if your servers are expecting specific incoming headers.
  6. Select Save.

Prepare your servers

Make sure that your firewall or web server does not block or rate limit your configured health checks or requests associated with Cloudflare IP addresses.

Each health check has the HTTP user-agent of "Mozilla/5.0 (compatible; Cloudflare-Traffic-Manager/1.0; +https://www.cloudflare.com/traffic-manager/; pool-id: $poolid)", where the $poolid is the first 16 characters of the associated pool .

Create a monitor (API)

Set up the monitor

For a full list of monitor properties, refer to Create Monitor. If you need help with API authentication, refer to Cloudflare API Quickstart .

Request
curl -X POST \
-H "X-Auth-Email: user@cloudflare.com" \
-H "X-Auth-Key: REDACTED" \
"https://api.cloudflare.com/client/v4/accounts/:account_id/load-balancers/monitors" \
-H "Content-Type: application/json" \
-d '{
"type":"https",
"description":"Login page monitor",
"method":"GET",
"path":"/health",
"header": {
"Host":["example.com"],
"X-App-ID":["abc123"]
},
"port":8080,
"timeout":3,
"retries":0,
"interval":90,
"expected_body":"alive",
"expected_codes":"2xx",
"follow_redirects":true,
"allow_insecure":true,
"consecutive_up":3,
"consecutive_down":2,
"probe_zone":"example.com"
}'

The response contains the complete definition of the new monitor.

Response
{
"success": true,
"errors": [],
"messages": [],
"result": {
"id": ":monitor-id",
"created_on": "2021-01-01T05:20:00.12345Z",
"modified_on": "2021-01-01T05:20:00.12345Z",
"type": "https",
"description": "Login page monitor",
"method": "GET",
"path": "/health",
"header": {
"Host": [
"example.com"
],
"X-App-ID": [
"abc123"
]
},
"port": 8080,
"timeout": 3,
"retries": 0,
"interval": 90,
"expected_body": "alive",
"expected_codes": "2xx",
"follow_redirects": true,
"allow_insecure": true,
"consecutive_up": 3,
"consecutive_down": 2,
"probe_zone": "example.com"
}
}

Prepare your servers

Make sure that your firewall or web server does not block or rate limit your configured health checks or requests associated with Cloudflare IP addresses.

Each health check has the HTTP user-agent of "Mozilla/5.0 (compatible; Cloudflare-Traffic-Manager/1.0; +https://www.cloudflare.com/traffic-manager/; pool-id: $poolid)", where the $poolid is the first 16 characters of the associated pool .

Example monitor configuration
FieldValue
TypeHTTP
Path/
Port80
Interval60
MethodGET
Timeout5 seconds
Retries2
Expected Code(s)200

Step 2 — Create an origin pool

A pool is a group of origin servers, with each origin identified by its IP address or hostname.
Create a pool (dashboard)

You can create a pool within the load balancer workflow or in the Origin Pools section of the dashboard:

  1. Go to Traffic > Load Balancing.

  2. Click Manage Pools.

  3. Click Create.

  4. For your pool, enter the following information:

    • A name (must be unique)
    • A description to provide more detail on the name
    • A choice for Origin Steering , which affects how your pool routes traffic to each origin
  5. For each origin, enter the following information:

    • A name (must be unique)
    • The origin server address or associated hostname
    • A Weight
    • (Optional) A hostname by clicking Add host header
  6. Repeat this process for additional origins in the pool.

  7. (Optional) Set up coordinates for Proximity Steering on the pool.

  8. On the origin pool, update the following information:

    • Health Threshold: Number of healthy origins for the pool as a whole to be considered Healthy and receive traffic based on pool order in a load balancer
    • Monitor: Attach a monitor
    • Health Check Regions: Choose whether to check pool health from multiple locations , which increases accuracy but can lead to probe traffic to your origin
    • Notifications: If you do or do not want to receive notifications when the pool’s status changes
  9. When finished, click Save.

Create a pool (API)

For a full list of properties, refer to Create Pool. If you need help with API authentication, refer to Cloudflare API Quickstart .

Request
curl -X POST \
-H "X-Auth-Email: user@cloudflare.com" \
-H "X-Auth-Key: REDACTED" \
"https://api.cloudflare.com/client/v4/accounts/:account_id/load-balancers/pools" \
-H "Content-Type: application/json" \
-d '{
"description":"Primary data center - Provider XYZ",
"name":"primary-dc-1",
"enabled":false,
"load_shedding": {
"default_percent":0,
"default_policy":"random",
"session_percent":0,
"session_policy":"hash"
},
"minimum_origins":2,
"monitor":"f1aba936b94213e5b8dca0c0dbf1f9cc",
"check_regions": [
"WEU",
"ENAM"
],
"origins": [
{
"name":"app-server-1",
"address":"0.0.0.0",
"enabled":true,
"weight":0.56,
"header": {
"Host": [
"example.com"
]
}
}
],
"origin_steering": {
"policy": "random"
},
"notification_email":"someone@example.com,sometwo@example.com",
"notification_filter": {
"origin": {
"disable":false,
"healthy":null
},
"pool": {
"disable":false,
"healthy":null
}
}
}'

The response contains the complete definition of the new pool.

Response
{
"success": true,
"errors": [],
"messages": [],
"result": {
"id": "17b5962d775c646f3f9725cbc7a53df4",
"created_on": "2021-01-01T05:20:00.12345Z",
"modified_on": "2021-01-01T05:20:00.12345Z",
"description": "Primary data center - Provider XYZ",
"name": "primary-dc-1",
"enabled": false,
"load_shedding": {
"default_percent": 0,
"default_policy": "random",
"session_percent": 0,
"session_policy": "hash"
},
"minimum_origins": 2,
"monitor": "f1aba936b94213e5b8dca0c0dbf1f9cc",
"check_regions": [
"WEU",
"ENAM"
],
"origins": [
{
"name": "app-server-1",
"address": "0.0.0.0",
"enabled": true,
"weight": 0.56,
"header": {
"Host": [
"example.com"
]
}
}
],
"origin_steering": {
"policy": "random"
},
"notification_email": "someone@example.com,sometwo@example.com",
"notification_filter": {
"origin": {
"disable": false,
"healthy": null
},
"pool": {
"disable": false,
"healthy": null
}
}
}
}

Step 3 — Confirm pool health

Before directing any traffic to your pools, make sure that your pools and monitors are set up correctly. The status of your health check will be unknown until the results of the first check are available.

Confirm pool health (dashboard)
  1. Navigate to Traffic > Load Balancing.
  2. Click Manage Pools.
  3. For pools and individual origins, review the values in the Health and Origin Health columns.

For more information on pool and origin health statuses, refer to How a pool becomes unhealthy .

Confirm pool health (API)

To fetch the latest health status of all pools, use the List Pools command, paying attention to the healthy value for pools and origins.

For troubleshooting a specific pool’s health, use the Pool Health Details command.

Unexpected health status

If you notice that healthy pools are being marked unhealthy:

Step 4 — Create a load balancer on a test subdomain

A load balancer distributes traffic among origin pools according to pool health and its steering policy . Each load balancer is identified by its DNS hostname (lb.example.com, www.example.com, etc.).
Create a load balancer (dashboard)
  1. Go to Traffic > Load Balancing.

  2. Click Create Load Balancer.

  3. On the Hostname page:

    • Enter a Hostname, which is the DNS name at which the load balancer is available. For more details on record priority, refer to DNS records for load balancing .
    • Toggle the orange cloud icon to update the proxy mode , which affects how traffic is routed and which IP addresses are advertised.
    • If you want session-based load balancing , toggle the Session Affinity switch.
  4. Click Next.

  5. On the Add an Origin Pool page:

  6. Click Next.

  7. On the Monitors page:

    • Review the monitors attached to your pools.
    • If needed, you can attach an existing monitor or create a new monitor .
  8. Click Next.

  9. On the Traffic Steering page, choose an option for Traffic steering .

  10. Click Next.

  11. On the Custom Rules page, select an existing rule or create a new rule .

  12. Click Next.

  13. On the Review page:

    • Review your configuration and make any changes.
    • Choose whether to Save as Draft or Save and Deploy.
Create a load balancer (API)

For a full list of properties, refer to Create Load Balancer. If you need help with API authentication, refer to Cloudflare API Quickstart .

Request
curl -X POST \
-H "X-Auth-Email: user@cloudflare.com" \
-H "X-Auth-Key: REDACTED" \
"https://api.cloudflare.com/client/v4/zones/:zone_id/load-balancers" \
-H "Content-Type: application/json" \
-d '{
"description": "Load Balancer for lb.example.com",
"name": "lb.example.com",
"enabled": true,
"ttl": 30,
"fallback_pool": "17b5962d775c646f3f9725cbc7a53df4",
"default_pools": [
"17b5962d775c646f3f9725cbc7a53df4",
"9290f38c5d07c2e2f4df57b1f61d4196",
"00920f38ce07c2e2f4df50b1f61d4194"
],
"proxied": true,
"steering_policy": "dynamic_latency",
"session_affinity": "cookie",
"session_affinity_attributes": {
"samesite": "Auto",
"secure": "Auto",
"drain_duration": 100
},
"session_affinity_ttl": 5000,
}'

The response contains the complete definition of the new load balancer.

Response
{
"success": true,
"errors": [],
"messages": [],
"result": {
"id": "699d98642c564d2e855e9661899b7252",
"created_on": "2021-01-01T05:20:00.12345Z",
"modified_on": "2021-01-01T05:20:00.12345Z",
"description": "Load Balancer for lb.example.com",
"name": "lb.example.com",
"enabled": true,
"ttl": 30,
"fallback_pool": "17b5962d775c646f3f9725cbc7a53df4",
"default_pools": [
"17b5962d775c646f3f9725cbc7a53df4",
"9290f38c5d07c2e2f4df57b1f61d4196",
"00920f38ce07c2e2f4df50b1f61d4194"
],
"proxied": true,
"steering_policy": "dynamic_latency",
"session_affinity": "cookie",
"session_affinity_attributes": {
"samesite": "Auto",
"secure": "Auto",
"drain_duration": 100
},
"session_affinity_ttl": 5000,
}
}

Route traffic to your load balancer

Just as in the previous step, make sure your load balancer is functioning as you expected before using it with live traffic.

For example, if you had test.example.com as a testing subdomain, you could either:

  • Create a load balancer with a Hostname of test.example.com.
  • Create a load balancer with a different Hostname (lb.example.com) and set up a CNAME record on test.example.com that points to lb.example.com.

Either option would use your load balancer to distribute requests going to test.example.com.

Step 5 — Review load balancing analytics

As you send sample requests to your test domain, review the load balancing analytics page to make sure your load balancer is distributing requests like you were expecting.

Step 6 — Review DNS records and SSL/TLS coverage

Before you deploy your load balancer, review your DNS records and SSL/TLS coverage.

Sometimes, you might misunderstand the priority order for DNS records and route more or less traffic than intended to your load balancer.

Universal SSL certificates do not cover load balancing hostnames without existing DNS records. For additional details, refer to SSL/TLS coverage .

Step 7 — Deploy your load balancer on live traffic

Now that you have set up your load balancer and verified everything is working correctly, you can put the load balancer on a live domain or subdomain.

As before, you could either:

  • Edit the Hostname of your existing load balancer
  • Update the CNAME record sending traffic to your load balancer

Step 8 — Continue reviewing load balancing analytics

Repeat Step 5 to ensure your load balancer is acting as expected.