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
__cflbcookie. 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
- Audit current infrastructure — identify points of failure, user geography, session affinity requirements.
- Design topology — select regions, configure health checks, geo-routing rules.
- Implement via Terraform — create pools, load balancer, notifications; test in staging.
- Test failover — simulate failures, verify traffic switching.
- Deploy and monitor — apply to production, connect observability (Grafana + Prometheus for traffic counters).
- 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.







