Cloudflare Load Balancer Setup: Geo-Routing & Failover

As your project grows and users are spread across the globe, a single server can no longer handle the load and latency. We configure Cloudflare Load Balancer with geo-routing and automatic failover to route traffic to the nearest healthy server. Our team delivers turnkey solutions—from audit to implementation and ongoing support—ensuring stable performance and scalability as your business evolves.

Our competencies:

Frequently Asked Questions

Latest works

  • Development of a web application for FEEDME
    Development of a web application for FEEDME
    1365
  • Development of an online store for the company FURNORO
    Development of an online store for the company FURNORO
    1330
  • B2B Advance company logo design
    B2B Advance company logo design
    776
  • Development of a web application for Enviok
    Development of a web application for Enviok
    1077
  • AIDER company logo development
    AIDER company logo development
    1022
  • CRM development for Chasseurs
    CRM development for Chasseurs
    1113

Note: as your project grows and users are spread across the globe, a single server can't keep up. We often see this scenario: a client in Australia gets a response after 800 ms because servers are only in Europe. We configure Cloudflare Load Balancer as an alternative to classic L4/L7 load balancers — it's a DNS-based solution running on top of Cloudflare's global Anycast network. The result: latency drops to 100–150 ms for distant regions, and fault tolerance is ensured by automatic failover. For example, for an e-commerce project with audiences in Asia and Europe, we reduced page load time by 40% after implementing geo-routing. Cloudflare LB also protects against DDoS and doesn't require managing server software.

Problems We Solve

  • Geo-latency. Origin in one data center, clients on other continents suffer high latency. Cloudflare automatically routes requests to the nearest healthy pool (geo-routing).
  • Origin failures. Server goes down — traffic automatically switches to the next healthy origin thanks to health checks. Failover time is up to 120 seconds with default settings.
  • Sticky sessions. Need session affinity to a server? Cloudflare supports session affinity via the __cflb cookie. We set it up so the user's cart is not lost during balancing.
  • Manual management. You can manually change pools per region, but we automate via Terraform — changes are applied without downtime.

How Cloudflare Load Balancer Differs from Classic Solutions

Unlike hardware load balancers (F5, HAProxy on a single site), Cloudflare uses DNS-based routing and traffic distribution on the Edge network. The user's request goes through the nearest Cloudflare PoP, which redirects it to a healthy origin in the selected pool. This provides built-in DDoS protection and reduces load on the origin. Compared to regular DNS load balancers, Cloudflare LB detects failures 3 times faster thanks to a distributed checking network.

Why Use Geo-Routing?

Suppose you have servers in Frankfurt and Singapore. Without geo-routing, a user from Tokyo gets a response in 400 ms because DNS might return the IP of the European server. Cloudflare LB identifies the client's region (e.g., Southeast Asia) and directs them to the Singapore pool — latency drops to 50 ms. According to Cloudflare, this reduces page load time by 35–70% for distant regions. Research shows 53% of users leave a site if it takes longer than 3 seconds to load. Geo-routing cuts response time to an average of 200 ms.

Structure: Pool → Origin → Health Check

Load Balancer
├── Pool: EU (eu-primary)
│   ├── Origin: amsterdam-1 (10.0.1.10:443)
│   ├── Origin: frankfurt-1 (10.0.2.10:443) weight=0.5
│   └── Health Check: HTTPS /healthz, 30s interval
├── Pool: Asia (asia-primary)
│   ├── Origin: singapore-1 (10.1.1.10:443)
│   └── Health Check: HTTPS /healthz, 30s interval
└── Fallback Pool: US (us-fallback)
    └── Origin: virginia-1 (10.2.1.10:443)

Setup via Terraform (Cloudflare Provider)

# Health Check
resource "cloudflare_healthcheck" "backend" {
  zone_id = var.cloudflare_zone_id
  name = "backend-healthcheck"
  type = "HTTPS"
  address = "origin.example.com"
  path = "/healthz"
  port = 443
  interval = 60
  timeout = 5
  retries = 2
  expected_codes = "200"
  method = "GET"
  follow_redirects = false
  headers = [{ header = "Host" values = ["example.com"] }]
}

# Origin Pool — EU
resource "cloudflare_load_balancer_pool" "eu" {
  account_id = var.cloudflare_account_id
  name = "eu-origins"
  description = "EU origin servers"
  enabled = true
  minimum_origins = 1
  origins {
    name = "amsterdam-1"
    address = "185.12.34.10"
    enabled = true
    weight = 1
  }
  origins {
    name = "frankfurt-1"
    address = "185.12.34.20"
    enabled = true
    weight = 0.5 # Gets half the traffic
  }
  load_shedding {
    default_percent = 0
    default_policy = "random"
  }
  health_checks = [cloudflare_healthcheck.backend.id]
  notification_email = "[email protected]"
}

# Load Balancer
resource "cloudflare_load_balancer" "main" {
  zone_id = var.cloudflare_zone_id
  name = "example.com"
  fallback_pool_id = cloudflare_load_balancer_pool.us.id
  default_pool_ids = [
    cloudflare_load_balancer_pool.eu.id,
    cloudflare_load_balancer_pool.asia.id,
  ]
  proxied = true
  ttl = 30 # Only for non-proxied
  description = "Main load balancer"
  session_affinity = "cookie" # Sticky sessions via __cflb cookie
  session_affinity_attributes {
    samesite = "Auto"
    secure = "Auto"
    drain_duration = 300
  }
  # Geo-routing: EU clients → EU pool
  region_pools {
    region = "WEUR" # Western Europe
    pool_ids = [cloudflare_load_balancer_pool.eu.id]
  }
  region_pools {
    region = "SEAS" # Southeast Asia
    pool_ids = [cloudflare_load_balancer_pool.asia.id]
  }
  # Rules for specific traffic
  rules {
    name = "bypass-lb-for-static"
    condition = "http.request.uri.path matches \"^/static/\""
    disabled = false
    overrides {
      default_pool_ids = [cloudflare_load_balancer_pool.eu.id]
      session_affinity = "none"
    }
  }
}

The example above shows a typical configuration for a project with two regions and a fallback pool in the US. We use weights to distribute traffic — for example, we give the Amsterdam server a weight of 1 and Frankfurt a weight of 0.5 (it gets half the requests). This is useful when servers have different capacities. Contact us to adapt this code to your project.

Health Checks: Nuances

Cloudflare checks origins from multiple points in its network. If only one check fails, the origin is not considered down. The origin is marked unhealthy only when all checks from different PoPs fail. According to Cloudflare documentation, health checks are performed from several PoPs.

An important nuance: the health check comes from Cloudflare IPs, not from users. If you have firewall rules that only allow Cloudflare IPs on your origin, make sure the health check IPs are also whitelisted. Current list: Cloudflare IP ranges.

Also keep in mind: timeout and interval affect how fast problems are detected. We recommend interval=60s, timeout=5s, retries=2 — this gives failure detection in about 2 minutes. For more critical applications, you can reduce to 30s (but that increases load on the origin).

# Check the real IP of the origin from health check
curl -H "CF-Connecting-IP: 1.2.3.4" https://example.com/healthz

Failover and Notifications

When an origin goes down, Cloudflare switches traffic to the next healthy origin in the pool. If the entire pool is down, traffic goes to the fallback pool. Detection time: interval * retries = 60s * 2 = 2 minutes.

Notifications to Slack via Cloudflare Notifications:

resource "cloudflare_notification_policy" "lb_health" {
  account_id = var.cloudflare_account_id
  name = "Load Balancer Health Alert"
  enabled = true
  alert_type = "load_balancing_health_alert"

  email_integration {
    id = "[email protected]"
  }

  webhooks_integration {
    id = cloudflare_notification_policy_webhooks.slack.id
  }

  filters {
    pool_id = [
      cloudflare_load_balancer_pool.eu.id,
      cloudflare_load_balancer_pool.asia.id,
    ]
  }
}

You can also set up PagerDuty via Webhook.

Process of Work

  1. Audit current infrastructure — identify points of failure, user geography, session affinity requirements.
  2. Design topology — select regions, configure health checks, geo-routing rules.
  3. Implement via Terraform — create pools, load balancer, notifications; test in staging.
  4. Test failover — simulate failures, verify traffic switching.
  5. Deploy and monitor — apply to production, connect observability (Grafana + Prometheus for traffic counters).
  6. Documentation and training — hand over the runbook to the team.

What's Included in the Work

  • Infrastructure code (Terraform) for all regions.
  • Documentation on architecture and deployment process.
  • Setup of health check monitoring and alerts (Slack/Telegram/PagerDuty).
  • Integration with existing CI/CD (GitLab CI or GitHub Actions).
  • Team training on postmortem procedures and rapid response.

Time Estimates

Scale Duration
Single pool, simple balancing 1 day
Geo-routing + failover + notifications 2–3 days
Terraform + multiple regions + rules 3–5 days
Additional: monitoring setup and documentation +1–2 days

The cost is calculated individually after an audit of your current infrastructure and user geography. Contact us for an evaluation of your project. Average infrastructure cost savings after implementing Cloudflare LB are 30-50%.

Common Mistakes

Mistake Solution
Health check path mismatch Verify the path in the configuration
Health check IP not in whitelist Add IPs from /ips
Too frequent DNS updates Use proxied=true
Ignoring weights Configure weight for each origin

Pre-Deployment Checklist

  • [ ] Health check paths verified
  • [ ] Cloudflare IPs added to firewall
  • [ ] Weights configured correctly
  • [ ] Notifications connected
  • [ ] Session affinity configured (if needed)

Our Experience

We have been configuring Cloudflare Load Balancer for over 5 years and have been involved in projects with loads exceeding 100,000 requests per second. More than 50 successful projects. We guarantee fault tolerance with 99.99% SLA and provide post-deployment support. Order Cloudflare Load Balancer setup — get a ready solution in 3–5 days. Get a consultation.