Load Balancing — Full Curriculum

Personal study reference, not customer-facing. Covers the real architecture (monitors → pools → load balancer), all seven steering methods with accurate plan gating, the health-monitor gotchas that cause "my monitor says healthy but the site is down" tickets, session affinity mechanics, the new Pool Sets feature, and corrected pricing. Every fact below is sourced from live Cloudflare docs, including a Load Balancing Reference Architecture doc with real formulas (full list at the bottom).

Module 1Fundamentals & architecture

Load Balancing means more than one server can answer a request, and Cloudflare decides which one actually gets each request in real time — continuously checking health, and routing away from anything unhealthy with nobody having to notice or flip a switch.

Two layers, combined into one config

Load balancing for global applications traditionally comes in two layers: Global Traffic Management (GTM) — routing requests to the right region/data center, usually at the DNS layer — and Private Network Load Balancing — steering traffic to the final endpoint within a data center. Cloudflare has offered cloud-based GTM since 2016 and added Private Network Load Balancing capabilities starting 2023. Most vendors require separate hardware/SaaS for each layer; Cloudflare combines both into a single load balancer configuration — no need to chain a GTM product into a separate local load balancer.

The anycast advantage

Cloudflare's network uses anycast — the same IP is announced from every data center worldwide, so traffic always lands at the closest one and the load spreads naturally across the network during spikes. Most other SaaS load balancing providers use unicast, where one IP maps to one endpoint/data center — meaning performance depends heavily on how far a given user is from that single location, and scaling means ramping up that one location rather than sharing load across many.

The three components, in order

  1. Health Monitors — watch each endpoint, mark it healthy or critical.
  2. Endpoint Pools — groups of endpoints (usually one pool per data center/region); health monitors and endpoint steering are applied here.
  3. Load Balancer (VIP) — the entry point, typically a DNS record; applies traffic steering to pick a pool, then endpoint steering to pick a server inside it.

A request hits the Load Balancer's entry point → traffic steering picks which pool handles it (usually by region/latency) → endpoint steering picks the specific server inside that pool. If a pool or endpoint fails its health check, both steps redo themselves automatically using whatever's still healthy.

Module 2Steering methods

This is the part that actually determines whether a customer needs to pay for anything beyond the base product.

The seven methods — accurate table

MethodWhat it doesTraffic steeringEndpoint steeringWeight-basedPlan
Off / FailoverStrict priority order — first healthy pool/endpoint wins✓——All plans
RandomRandom selection, honors configured weights✓✓✓All plans
HashSame source IP always lands on the same endpoint—✓✓Enterprise
GeoTies pools to specific countries/regions✓——Enterprise or self-serve add-on
Dynamic (Latency)Builds a real round-trip-time profile per pool, routes to lowest RTT✓——Enterprise or self-serve add-on
ProximityRoutes to the physically closest data center by GPS coordinates✓——Enterprise or self-serve add-on
Least Outstanding Requests (LORS)Routes to whichever endpoint has the fewest open requests✓✓✓Enterprise or self-serve add-on

Say it like this: "The basic version just needs someone to be alive and answering. The smarter versions — latency-based, closest-data-center, least-busy-server — are Enterprise-tier capabilities, but you don't have to sign a full Enterprise contract to get them. All the traffic-steering methods above marked Enterprise are also available as a self-serve add-on." Hash is the one exception — it's endpoint-steering only and is Enterprise-only without the self-serve add-on path mentioned for the others.

Weight math

Weight is any number 0.00–1.00. Weights in a pool don't need to sum to 1 — probability of selection is weight ÷ sum of all weights. Weight is only used by Random, Hash, and LORS.

// Three pools, weights 0.4 / 0.5 / 0.6
Pool A: 0.4 / (0.4+0.5+0.6) = 26.67%
Pool B: 0.5 / (0.4+0.5+0.6) = 33.33%
Pool C: 0.6 / (0.4+0.5+0.6) = 40.00%

LORS transforms weight using open-request counts: weight ÷ (open_requests + 1) = transformed_weight, then applies the same probability formula to the transformed weights. With Pool A at weight 0.4 and 3 open requests vs. Pool B at weight 0.6 and 0 open requests, Pool B ends up with an 85.7% chance of being chosen on the next request, even though its raw weight advantage was only 0.6 vs 0.4. LORS only works meaningfully on Layer 7 proxied load balancers — see Module 7 for what happens elsewhere.

The gotcha that causes "why isn't my weighted steering working" tickets: session affinity overrides weight after the first connection — once a user is pinned to an endpoint, weight stops applying to them. A customer testing a canary rollout with weighted steering will see skewed results if returning users are already session-pinned from a prior visit. Flag this explicitly whenever weighted steering and session affinity are both in play.

Module 3Health monitors

Health monitors are templates (service type, path, port, interval, timeout) that get applied to a pool's endpoints. They're account-level objects — one monitor can be reused across multiple zones in the same account.

Probe types & minimum intervals by plan

PlanProbe typesMinimum interval
ProHTTP, HTTPS, TCP60 seconds
BusinessHTTP, HTTPS, TCP15 seconds
EnterpriseHTTP, HTTPS, TCP, UDP ICMP, ICMP Ping, SMTP10 seconds

Faster detection is a real, tangible plan-tier difference worth mentioning on any call about downtime. Note: Cloudflare's Load Balancing reference architecture doc also lists an LDAP probe type, but the plan-gating page doesn't confirm which plan it requires — don't commit to a specific plan tier for LDAP without checking current docs at config time.

Retry timing — the real math

Retries fire immediately on a timeout, they do not wait for the next interval. With a 20-second timeout and 5 retries, that's 6 total attempts (~120 seconds) before an endpoint is marked unhealthy — plan your interval/retry combination around how fast you actually need failover to kick in, not just the headline interval number.

Simulate Zone — the gotcha that causes false "healthy" status

By default, health monitor probes bypass the entire Layer 7 stack and go straight to the endpoint address. This means a probe can report "healthy" even while real traffic through the load balancer is failing, because real traffic and the health check take different paths. Simulate Zone forces probes through the same Layer 7 path as real requests, and is required when the zone uses Authenticated Origin Pulls (mTLS), Origin CA, Argo Smart Routing, or Dedicated CDN Egress IPs (Smart Shield Advanced) — otherwise those probes fail or get mismatched treatment.

Pool health states — three tiers, not binary

StateMeaning
HealthyAll endpoints in the pool are healthy
DegradedAt least one critical endpoint, but still at/above the configured Health Threshold
CriticalHealthy endpoint count below threshold — the entire pool is removed from all steering decisions

Monitor health regions & Monitor Groups

Probes can be sourced from specific regions: Western/Eastern North America, Western/Eastern Europe, Northern/Southern South America, Oceania, Middle East, Northern/Southern Africa, Southern/Southeast/Northeast Asia, or All Regions (default). All Data Centers is Enterprise-only.

Monitor Groups (Enterprise, API-only configuration) combine multiple independent monitors per pool — e.g. an HTTP check on the API gateway and a TCP check on a dependency — so a pool is only healthy if all its critical components actually work. Uses a must_be_healthy override for critical monitors plus a quorum rule (more than 50% of non-excluded monitors must report unhealthy to mark the endpoint down); monitors flagged monitoring_only don't count toward quorum. When combined with Dynamic Steering, pool latency becomes the average latency across all enabled, non-monitoring-only monitors in the group.

Module 4Pools, endpoints & Tunnel integration

Endpoint configuration rules

Cloudflare Tunnel as a load balancer endpoint

A single cloudflared instance creates 4 tunnels across 2 different Cloudflare data centers for high availability. Tunnel-based endpoints must be addressed via a cfargotunnel.com hostname — a CNAME pointing to it will not work. Tunnel endpoints default to ports 80/443; routing other ports needs a catch-all rule. For private IP/subnet tunnels specifically, you cannot specify a port — the entire subnet (even a single /32) becomes reachable through the tunnel, gated instead by Zero Trust access policies on the selected Virtual Network, not by port restriction.

Module 5Session affinity

For things like a shopping cart, you don't want a user bounced to a different server mid-session and losing their state. Session affinity pins them to one endpoint.

Three types, not just "cookie vs header"

  1. Cloudflare cookie only
  2. Cloudflare cookie + Client IP fallback
  3. HTTP header-based

Only Public (proxied) load balancers support session affinity — DNS-only mode doesn't (use DNS-level persistence instead there).

TTL and reset behavior — a real, documented difference

TTL range is 30 minutes to 7 days, default 23 hours. The two mechanisms behave differently on activity: cookie-based affinity's timer never resets — it counts down from session start regardless of ongoing activity. HTTP header-based affinity resets the timer on every request. Know which one a customer has configured before promising how long a pin will last.

Reminder from Module 2: session affinity overrides weighted steering after the first connection for a given user — this is the single most common "why isn't my weight working" root cause.

Module 6Custom Rules & Pool Sets

Custom Rules

Route based on URL path, ASN, headers, or other request attributes — similar to WAF custom rules. Non-Enterprise accounts get one rule per load balancer hostname by default; more requires Enterprise. Custom Rules are not supported on Spectrum (Layer 4) load balancers at all.

Pool Sets — new, API-only (Aug 2026)

Pool Sets combine geographic matching (by data center, country, or region) with location-specific traffic steering, pool weights, and fallback pools — all in a single load balancer config. Rules are evaluated first-match-wins in array order, and a matched rule can even return a fixed HTTP response directly instead of routing to a pool. API-only — no dashboard UI as of this writing. For API-managed load balancers, Pool Sets can replace Geo steering — Geo steering itself still exists separately, is dashboard-managed, uses one global fallback, and can't split traffic differently within the same location the way Pool Sets can.

Evaluation order: Pool Sets are evaluated before Custom Rules; Custom Rules apply as overrides on top of the Pool Set result — unless the matched Pool Set rule returned a fixed_response, in which case Custom Rules never run for that request.

Module 7Layer 4 vs Layer 7 & zero-downtime failover

Spectrum (Layer 4) load balancer differences

Zero-Downtime Failover

Three modes: None, Temporary, Sticky. Scope is narrow — it only triggers on a single retry, and only for 521/522/523/525/526 error codes, nothing else. Sticky mode is not supported with HTTP-header-based session affinity.

DNS-only load balancer weighting gotcha

If a DNS-only (unproxied) load balancer has even one endpoint with a unique weight configured, Cloudflare returns only a single IP address in the DNS response — not the full set you might expect. This is a sharp, counter-intuitive gotcha worth flagging before a customer configures weighted steering on a DNS-only setup expecting round-robin-style multi-IP responses.

Module 8Pricing & decision framework

Pricing — corrected

Load Balancing is not simply "per load balancer + per monitored origin." It's an add-on subscription starting at a flat $5/month, layered on top of a paid zone plan (Pro or above — it's not available on Free at all). Billing then breaks into separate metered line items for pools, origins (monitored endpoints), health-check intervals, and health-check regions — many of these line items show $0.00 if usage is within the included allocation, but don't describe it to a customer as a simple flat per-LB or per-origin fee. Load Balancing Analytics specifically requires a paid zone plan (Pro, Business, or Enterprise).

Decision framework

Symptom / scenarioLikely answer
"Our one server fell over last month"Basic failover (Off/Failover) + health monitors — the foundational win, available on every paid-LB plan
Global users complaining about latency to one originDynamic (Latency) or Proximity steering
Data residency / compliance requirementGeo steering (dashboard) or Pool Sets (API-managed LBs)
Traffic spikes overwhelm specific endpoints unevenlyLeast Outstanding Requests — but confirm the LB is Layer 7 proxied first
Shopping cart / session state getting lost mid-visitSession affinity (cookie, cookie+IP fallback, or header) — Public/proxied LB only
Health check says healthy, real traffic is failingSimulate Zone — probes are bypassing the L7 stack by default
Private IP origins behind a firewallVirtual Network + Cloudflare Tunnel (4 tunnels/2 DCs for HA) as the endpoint
Need different steering per country in one API-managed configPool Sets

Mistakes SEs make here

  1. Presenting all seven steering methods as equally relevant. Diagnose the actual symptom (downtime vs. latency vs. compliance) first, then present the one or two methods that solve it — don't lead with jargon.
  2. Implying Enterprise-only steering requires a full Enterprise contract. It doesn't — Geo, Dynamic, Proximity, and LORS (as traffic steering) are all available as a self-serve add-on. Telling a Pro/Business customer they need a full Enterprise deal to get Dynamic steering is factually wrong and needlessly kills a smaller, faster deal. (Hash steering is the one genuine exception — Enterprise only, no add-on path.)
  3. Forgetting session affinity overrides weighting after the first request. A canary rollout test with weighted steering will look broken if returning users are already session-pinned — always ask if affinity is also configured before troubleshooting "my weights aren't working."
  4. Assuming a passing health check means real traffic is healthy. Without Simulate Zone, the two can diverge completely — especially on zones using mTLS, Origin CA, Argo, or Dedicated Egress IPs.

Module 9Verify & troubleshoot via API

Load Balancing is API-driven end to end — useful for Terraform/CI/CD-managed customers, and for verifying state live on a call. Required token permission: Load Balancing: Monitors and Pools Write.

Check a load balancer's live config

curl -s "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/load_balancers/$LB_ID" \
  -H "Authorization: Bearer $CF_API_TOKEN" | jq .

Check real-time pool health — the fast way to resolve "is it actually healthy?"

curl -s "https://api.cloudflare.com/client/v4/accounts/$ACCOUNT_ID/load_balancers/pools/$POOL_ID/health" \
  -H "Authorization: Bearer $CF_API_TOKEN" | jq .
// Returns live healthy/degraded/critical status per monitor region —
// faster to pull live on a call than walking through the dashboard.

Preview a monitor before committing it

curl -s -X POST "https://api.cloudflare.com/client/v4/accounts/$ACCOUNT_ID/load_balancers/monitors/$MONITOR_ID/preview" \
  -H "Authorization: Bearer $CF_API_TOKEN" | jq .
// Tests a monitor definition against the pools it would attach to,
// without waiting for a live interval cycle to pass.

Pull usage (billing-relevant line items)

curl -s "https://api.cloudflare.com/client/v4/accounts/$ACCOUNT_ID/load_balancers/usage" \
  -H "Authorization: Bearer $CF_API_TOKEN" | jq .
// Good for the "what are we actually being charged for" conversation —
// shows pools/origins/interval/region usage separately.

Module 10Rapid-fire Q&A

"Our health check says everything's healthy, but customers say the site is down."

Classic Simulate Zone gap — by default, health probes bypass the entire Layer 7 stack and go straight to the origin, so they can pass even while real proxied traffic fails. Enable Simulate Zone so probes follow the same path as real requests. This is required, not optional, if the zone uses Authenticated Origin Pulls, Origin CA, Argo, or Dedicated CDN Egress IPs.

"I set up weighted steering 70/30 but it's not distributing that way."

Check for session affinity first — it overrides weight after a user's first connection. Also remember weight-based distribution only converges toward the configured ratio at real traffic volume; small sample sizes will look skewed even with affinity off.

"Can we get Dynamic/Latency steering without going full Enterprise?"

Yes — Geo, Dynamic, Proximity, and LORS traffic steering are all available as a self-serve add-on, not gated behind a full Enterprise contract. Hash steering is the one exception that's genuinely Enterprise-only.

"Our origin is behind a firewall with a private IP — can Load Balancing still reach it?"

Yes, via a Virtual Network + Cloudflare Tunnel. Address the endpoint using its cfargotunnel.com hostname (a CNAME to it won't work), and remember private subnet tunnels can't restrict by port — the whole subnet becomes reachable, gated by Zero Trust policy instead.

"What's the actual monthly cost?"

Starts at a flat $5/month add-on on top of a paid zone plan (Pro+), with separate metered line items for pools, origins, health-check intervals, and health-check regions. Don't quote it as a simple per-load-balancer or per-origin number — pull the live usage/billing page instead.

"Does Load Balancing work if we're DNS-only, not proxied?"

Partially — DNS-only load balancers exist, but session affinity isn't available in that mode (use DNS-level persistence instead), and if even one endpoint has a unique weight configured, the DNS response collapses to returning a single IP rather than the full set.

Self-testQuiz

Click a question to reveal the answer. No peeking before you commit to one.

1. How many documented steering methods does Cloudflare Load Balancing actually offer?

Seven: Off/Failover, Random, Hash, Geo, Dynamic, Proximity, and Least Outstanding Requests. Hash is the one that's easy to forget since it's endpoint-steering only.

2. Which steering method is Enterprise-only with NO self-serve add-on path, unlike Geo/Dynamic/Proximity/LORS?

Hash steering. The others marked Enterprise are all also purchasable as a self-serve add-on without a full Enterprise contract — Hash is the exception.

3. A customer has weighted steering configured 70/30 but traffic isn't distributing that way. First thing to check?

Whether session affinity is also enabled — it overrides weighted steering after a user's first connection, pinning them regardless of configured weight.

4. A health monitor reports an endpoint as healthy, but real customer traffic through the load balancer is failing. What's the likely cause?

Health probes bypass the entire Layer 7 stack by default and go straight to the origin — so they can diverge from what real proxied traffic experiences. Enable Simulate Zone so probes follow the same path as real requests.

5. Name two features that specifically require Simulate Zone to work correctly with health monitors.

Any two of: Authenticated Origin Pulls (mTLS), Origin CA, Argo Smart Routing, or Dedicated CDN Egress IPs (Smart Shield Advanced) — probes need to follow the real traffic path for these to be evaluated correctly.

6. What are the three endpoint pool health states, and what distinguishes "degraded" from "critical"?

Healthy, Degraded, Critical. Degraded has at least one unhealthy endpoint but is still at/above the configured Health Threshold — it keeps serving traffic. Critical is below the threshold — the entire pool is removed from all steering decisions.

7. What are the minimum health-check intervals for Pro, Business, and Enterprise, and what's the real-world retry-timing gotcha?

60s (Pro), 15s (Business), 10s (Enterprise). The gotcha: retries fire immediately on timeout rather than waiting for the next interval — with a 20s timeout and 5 retries, that's ~120 seconds total before an endpoint is marked unhealthy, regardless of the configured interval.

8. A customer wants to point a load balancer endpoint at an origin behind a firewall with a private IP, reached via Cloudflare Tunnel. Two real gotchas to mention?

(1) The endpoint must be addressed via its cfargotunnel.com hostname — a CNAME to it won't work. (2) Private IP/subnet tunnels can't restrict by port — the whole subnet becomes reachable, gated by Zero Trust access policy instead of a port restriction.

9. Cookie-based vs. HTTP header-based session affinity — what's the real difference in how their TTL behaves?

Cookie-based affinity's timer never resets — it counts down from session start regardless of activity. Header-based affinity resets the timer on every request. Same default (23h) and range (30min-7d), different reset behavior.

10. True or false: session affinity works the same way on a DNS-only (unproxied) load balancer as on a proxied one.

False — session affinity only applies to Public (proxied) load balancers. DNS-only mode doesn't support it at all; use DNS-level persistence instead.

11. What happens to a DNS-only load balancer's DNS response if even one endpoint has a unique weight configured?

Cloudflare returns only a single IP address in the DNS response instead of the full endpoint set — a sharp, counter-intuitive gotcha for anyone expecting round-robin-style multi-IP answers.

12. What's genuinely new about Pool Sets (Aug 2026), and how is it different from Geo steering?

Pool Sets let one load balancer apply different steering policies, pool weights, and fallback pools to different geographies in a single config (API-only, first-match-wins). Geo steering is dashboard-managed, uses one global fallback, and can't split traffic differently within the same location the way Pool Sets can.

13. How many Custom Rules does a non-Enterprise account get per load balancer hostname by default?

One. More requires Enterprise. Also: Custom Rules aren't supported on Spectrum (Layer 4) load balancers at all.

14. On a Spectrum (Layer 4) load balancer, which session affinity option(s) are available?

Only Hash endpoint steering — no cookie-based or header-based options exist at Layer 4.

15. What happens to Least Outstanding Requests (LORS) steering on a non-Layer-7-proxied load balancer?

It silently degrades to pure weighted/random selection — the "open request count" LORS needs isn't available outside L7 proxying, so the denominator in its formula always becomes 1, which mathematically reduces it to weight-only steering.

16. A customer asks what Load Balancing actually costs per month. What's the accurate answer?

A flat $5/month add-on on top of a paid zone plan (Pro or above — not available on Free), plus separate metered line items for pools, origins, health-check intervals, and health-check regions. It is not simply "per load balancer plus per monitored origin" — pull the live usage page for exact numbers rather than quoting from memory.

17. Which two zero-downtime failover error-code conditions trigger a retry, and what's the retry scope?

521/522/523/525/526 error codes trigger it, but only for a single retry — it's a narrow safety net, not a general retry policy. Also: Sticky mode isn't supported with HTTP-header-based session affinity.

Sources Load Balancing Reference Architecture Load Balancing overview Origin-level (endpoint) steering Pool Sets Pool Sets changelog Monitors overview Create Monitor — intervals & types by plan Monitor Groups Create Pool — endpoint rules Override HTTP Host headers Session affinity Load Balancing Rules (Custom Rules) Load Balancing Analytics How billing works (LB line items) Network/CDN add-on pricing Load Balancing with Spectrum