Networking AWS

Anycast at the Edge: Global Accelerator-Style TCP/UDP Routing for Latency and Failover

DNS-based global load balancing is the default answer for multi-region traffic, and for stateless HTTP it is usually fine. For TCP and UDP workloads where the protocol cannot be reverse-proxied at L7 — game servers, MQTT and AMQP brokers, SIP and RTP, database front ends, syslog collectors, custom binary protocols, anything that needs source-IP preservation or a hardcodable address — DNS-based global traffic management (GTM) is the wrong tool. Resolver and application caching make failover slow and unpredictable, and the client still traverses the public internet end to end to reach your origin. This article builds the alternative that every major cloud now ships: anycast static IPs that get clients onto the cloud provider’s private backbone at the nearest point of presence (PoP), with per-region weighting and sub-minute, health-driven failover. The reference implementation people reach for is AWS Global Accelerator, but the pattern — one IP, many PoPs, BGP-driven nearest entry, backbone the rest of the way — is the same on Azure (Front Door for HTTP, Cross-region Load Balancer for raw L4) and on Google Cloud (the global external Application and Network Load Balancers on Premium Tier). This is a cross-cloud, decision-grade treatment: what the mechanism actually is, when it beats DNS, how each cloud implements it, and the exact config and trade-offs.

The single idea that makes all of this work is decoupling the client’s entry point from where your application runs. A client sends a SYN to one static IP; the packet lands at whatever edge is nearest in BGP terms; the accelerator terminates or forwards that flow and carries it over a congestion-managed private backbone to a healthy regional endpoint. You can add, drain, or lose an entire region and the client never sees a different address, never re-resolves DNS, and — for the long transcontinental leg — never touches the public internet. That is why anycast accelerators cut both latency (shorter public hop, faster backbone) and jitter (backbone paths are engineered, transit paths are not), and why they fail over in seconds instead of the tens of seconds to minutes a DNS TTL plus resolver caching plus client caching imposes.

By the end you will be able to decide — for a specific protocol, failover budget, and blast radius — whether you want an anycast accelerator or DNS GTM (or both, layered), pick the right product on each cloud, and stand it up with real CLI and IaC. You will also understand the parts that bite in production: cold-potato edge onramp, why a “traffic dial” is a per-region ceiling and not a cross-region weight, what client-IP preservation costs you in firewall design, and why anycast protects the reconnect but not the in-flight connection on a failed box. This is the layer a senior network architect reaches for when “just use Route 53 latency records” stops being an acceptable answer.

What problem this solves

The pain is specific and it shows up in incident reviews, not in design diagrams. You run a stateful L4 service in two or three regions. You steer clients with DNS — Route 53 latency records, Azure Traffic Manager, Google Cloud DNS geo/failover routing, or a third-party GTM like NS1. It works in the demo. Then a region has a partial impairment at 3am, and the clients that resolved your record ninety seconds ago keep hammering the dead region until their cache expires. You do not control their cache; you control only your TTL, and half your clients ignore it. A Java client with the historical default networkaddress.cache.ttl caches forever. A mobile SDK resolves at session-join and pins the address for the whole session. A game client holds a UDP flow to an IP for the length of a match. DNS never sees a packet after the first answer, so it cannot un-steer a client that already has an address.

The second half of the pain is the path. With DNS steering, the client connects directly to your regional public endpoint over the public internet, across whatever transit providers, peering disputes, and congested ocean cables sit between them. For a request-response HTTP call from a nearby client, fine. For a distant client on a long-lived stateful connection — a trader’s market-data feed, a video-conference media stream, a multiplayer session — every packet rides that unengineered path, and the jitter and loss are visible to the user. You cannot fix the public internet, but you can minimise how much of it the client uses: get them onto the cloud backbone at the nearest edge and ride the engineered network the rest of the way.

Who hits this: anyone running non-HTTP or stateful workloads across regions, anyone who needs a static IP clients can hardcode (firewall allowlists, license servers, IoT devices flashed with an address, financial counterparties that whitelist IPs), anyone whose failover SLA is measured in seconds rather than minutes, and anyone whose distant users complain about lag that “isn’t the app, it’s the network.” The anycast accelerator is the tool that removes DNS from the failover path and removes most of the public internet from the data path — for exactly the workloads where DNS GTM quietly fails.

To frame the whole field before the deep dive, here is the landscape of what “global entry” can mean, and where anycast accelerators sit:

Approach Steering mechanism Layer Failover speed Static IP? Best for
DNS GTM (Route 53, Traffic Manager, Cloud DNS, NS1) DNS answer (A/AAAA/CNAME) L3 name resolution TTL + resolver + client cache (tens of sec → min) No (clients cache) Stateless HTTP, coarse geo-steering, cost-sensitive
Anycast L7 accelerator (Front Door, GCP global App LB, CloudFront-fronted) BGP to nearest PoP + edge proxy L7 (HTTP/S) Edge health check (seconds) Yes (anycast VIP) Global HTTP APIs and sites wanting edge TLS/WAF/cache
Anycast L4 accelerator (AWS Global Accelerator, Azure Cross-region LB, GCP global Network LB) BGP to nearest PoP + edge forward L4 (TCP/UDP) Edge health check (seconds) Yes (anycast VIP) Non-HTTP TCP/UDP, stateful, source-IP-preserving
BYOIP anycast (self-announced prefix on cloud) Your BGP prefix at cloud edges L3/L4 Depends on product on top Yes (your prefix) License/allowlist continuity, IP portability
Client-side steering (SDK picks region via health API) Application logic L7 app As fast as your client (seconds) N/A Bespoke control, no infra dependency, more code

Learning objectives

By the end of this article you can:

Prerequisites & where this fits

You should be comfortable with core networking: IP addressing and CIDR, TCP versus UDP and the notion of a connection or flow, DNS records and TTL, and the difference between L3, L4, and L7 processing. You should know what a regional load balancer is on your cloud of choice — an AWS Network Load Balancer (NLB) / Application Load Balancer (ALB), an Azure Standard Load Balancer / Application Gateway, or a GCP backend-service-based load balancer — because the anycast accelerator sits in front of these, not instead of them. Familiarity with BGP at a conceptual level (AS paths, route advertisement, local preference) helps you understand why anycast lands a client where it does, though you will not configure BGP yourself unless you use BYOIP.

This sits in the global connectivity and traffic-management track. It is downstream of regional load balancing and upstream of DNS. It pairs tightly with the DNS design articles because the honest answer is often “anycast for the data path, a friendly CNAME in front for humans.” If you run multi-region active-active apps, this connects directly to Cross-region Private Link and DNS for global active-active apps and to the resiliency framing in ExpressRoute private peering failover design. For the regional L4 building blocks the accelerator fronts, see AWS ALB vs NLB vs API Gateway compared. The outbound-side cousin of SNAT scaling shows up in NAT Gateway SNAT port exhaustion diagnosis and remediation, and the DNS-resolution mechanics that make GTM caching so hard to control are covered in Split-horizon DNS: multi-view internal and external resolution.

A quick map of who owns what during a global-entry incident, so you page the right person:

Layer What lives here Who usually owns it Failure classes it can cause
Client / SDK / resolver DNS cache, connection retry, IP pinning App / mobile team Stale-record steering, slow failover (DNS path)
DNS GTM Records, TTL, geo/latency/failover policy Network / SRE Failover lag, split-brain steering, propagation delay
Anycast edge (PoP) BGP announce, listener, edge health Cloud provider + you (config) Wrong PoP entry, listener/port mismatch, edge outage
Cloud backbone Private WAN between PoP and region Cloud provider Rare; provider-managed congestion/loss
Endpoint group / backend service Per-region landing, weights, health checks Network + app Health-check false positives, weighting mistakes
Regional LB (NLB/ALB/Std LB) Per-target balancing, TLS, target health App / platform Backend selection, target eviction
Origin (VMs/containers/EIP) Your service, source-IP handling App team Security-group blocks, loopback bind, app crash

Core concepts

Six mental models make every later decision obvious.

Anycast is one IP prefix announced from many places at once. A single IP range is advertised via BGP from many physical PoPs simultaneously. Every PoP says “reach this prefix through me,” and the global routing table resolves each client to whichever PoP is closest in BGP terms — fewest AS hops, best local preference at the client’s ISP — which in practice is the nearest edge. The client does nothing special; standard IP routing carries the first packet to the nearest announcement. On the accelerator products you get one or two static addresses out of this anycast space; you do not run BGP yourself unless you bring your own prefix (BYOIP).

The client never picks a region; the edge does the picking downstream. This is the whole point. The client sends its first packet to one static IP. It lands at the nearest PoP regardless of where your app runs. The accelerator then decides, at the edge, which regional endpoint should receive this flow — based on proximity, health, and your weighting. Move, add, or drain a region and the client’s target IP never changes. Contrast DNS, where the client is handed a region’s address and connects there directly; to change regions you must change what DNS hands out and wait for every cache to expire.

Cold-potato onboarding minimises the public-internet leg. Providers route traffic in one of two philosophies. Hot-potato routing hands traffic off to the next network as soon as possible (cheapest for the sender, worst for latency and jitter). Cold-potato routing keeps traffic on the provider’s own backbone as long as possible, onboarding it at the edge nearest the client and carrying it on-net to the destination. Anycast accelerators are cold-potato by design: the client reaches the edge over a short public hop, then rides the cloud’s engineered backbone across oceans and continents. Backbone paths have lower and tighter latency than transit paths, which is why the win is visible in both mean RTT and RTT standard deviation (jitter).

The path decomposes into two legs, and the accelerator changes the length and quality of the second one — which is where a transcontinental flow spends most of its time:

Path leg DNS-direct (public) Anycast accelerator Effect on the flow
Client → first hop Client ISP to transit Client ISP to nearest PoP Both short; comparable
Long transit leg Public transit across oceans/continents Provider backbone (engineered) Lower, tighter latency on anycast
Peering / handoffs Multiple AS boundaries, hot-potato Minimal — stays on-net Fewer congestion/jitter sources
Edge → origin region N/A (client is at origin) Backbone PoP → nearest region On-net, provider-managed
Dominant variability Transit congestion, peering disputes Backbone (well-managed) Jitter drops more than mean

L4 forwarding versus L7 termination is a real fork. Some anycast accelerators forward the L4 flow (they proxy TCP/UDP at the edge, preserve the protocol, and can preserve the client IP) — AWS Global Accelerator and Azure Cross-region Load Balancer are L4. Others terminate the connection at the edge as a full L7 proxy (they speak HTTP, can do TLS, WAF, caching, and header-based routing) — Azure Front Door and GCP’s global external Application LB are L7. GCP’s global external Network LB (and its passthrough variants) sit on the L4 side. Which you want depends entirely on your protocol: non-HTTP TCP/UDP needs L4; global HTTP that wants edge TLS/WAF/cache wants L7.

Health checks and thresholds set your failover clock. The accelerator continuously probes each regional endpoint. When an endpoint fails its check for a configured number of intervals, the edge stops sending it new flows and reroutes to the next-best endpoint. Failover time is roughly interval × unhealthy-threshold plus a few seconds of propagation. There is no DNS TTL and no client cache in this loop, which is why it is seconds, not minutes. The trade-off is sensitivity: too aggressive and a transient blip evicts a healthy region; too slow and you carry a dead region longer.

Anycast protects the reconnect, not the in-flight flow. When a regional endpoint dies, the TCP/UDP flows already pinned to it reset — the dead box is dead, and the accelerator cannot migrate a live socket to another region. What anycast guarantees is that when the client reconnects to the same static IP, it is steered to a healthy endpoint in seconds. Design your client to reconnect on reset/timeout to the same anycast address; then a regional failure is a brief reconnect, not a multi-minute outage. This single behaviour is the most-documented operational fact in every anycast deployment.

The vocabulary in one table

Before the deep sections, pin down every moving part. The glossary repeats these for lookup; this is the mental model side by side:

Concept One-line definition Where it lives Why it matters
Anycast IP One IP announced from many PoPs via BGP Provider edge (or BYOIP) The static, hardcodable entry point
PoP / edge A provider location that announces the anycast IP Global edge network Where the client actually enters
Cold-potato onramp Onboard at the edge nearest the client, ride backbone Provider network policy The latency/jitter win
Listener Ports + protocol the anycast IP accepts On the accelerator Defines TCP/UDP + port ranges
Endpoint group / backend Per-region landing zone with endpoints Per region Where the flow is delivered
Traffic dial Per-region ceiling on admitted traffic (0–100) AWS endpoint group Drain/ramp a region gracefully
Endpoint weight Relative share within a group AWS endpoint config Balance across in-region endpoints
Health check Probe deciding endpoint health On the accelerator/backend Sets the failover clock
Client affinity / stickiness Pin a client’s flows to one endpoint On the listener Required for per-client server state
Client-IP preservation Backend sees the real client IP Per endpoint / product Origin security, geo-filtering, audit
L4 forward vs L7 terminate Proxy the flow vs terminate HTTP Product design Decides protocol support
DNS GTM Global steering via DNS answers Authoritative DNS The thing anycast often replaces

Anycast versus DNS-based GTM: the decisive comparison

This is the decision most readers arrive with, so we lead with it. DNS-based steering — Route 53 latency/geo/failover records, Azure Traffic Manager, GCP Cloud DNS routing policies, NS1 Filter Chains — never sees a packet. It answers a query with an address and the client connects directly. That indirection is the source of every problem for stateful L4 traffic, and the source of DNS GTM’s genuine advantages too. Read both columns honestly.

Dimension DNS GTM Anycast accelerator
Steering signal DNS answer (A/AAAA), one-time per lookup BGP route to nearest PoP, per packet
Failover gate TTL + resolver cache + client/app cache Edge health check, no client cache
Realistic failover time tens of seconds to minutes seconds (interval × threshold + propagation)
Client data path public internet, full distance short hop to edge, then cloud backbone
Jitter / loss on long leg whatever transit gives you engineered backbone, lower and tighter
Source IP at origin client IP (direct connection) client IP (preserved) or edge IP, your choice
Hardcodable static IP no — clients cache stale answers yes — static for the accelerator’s life
Protocol scope any (it’s just an address) TCP/UDP (L4) or HTTP (L7), per product
Granular % split across regions yes (weighted records) coarse (geo-nearest + dials); precise % is awkward
Cost model cheap (per query + hosted zone) per-hour + per-GB premium
Blast radius of a bad change wide (propagation) but reversible narrow (config takes effect fast)

The failover row is the one that decides most L4 cases. With DNS, a client that resolved twenty seconds ago keeps connecting to the dead endpoint until its cache expires — and you control only your TTL, not resolver or application behaviour. With anycast the client holds an IP that never moves; when a regional endpoint fails its check, the edge reroutes new flows in seconds, no DNS change and no cache to wait on. For a request-response HTTP API you might not care about a 30-second gap. For a four-hour game session, a long-lived MQTT subscription, or a market-data feed, a 90-second window of clients stuck on a dead region is an incident with a name and a post-mortem.

But DNS GTM keeps real advantages, and pretending otherwise leads to over-engineering. It works for any protocol because it only hands out an address — there is nothing it cannot steer. It gives you precise weighted splits across regions (70/30, 90/10 canary) that anycast makes awkward. It is cheap — pennies per million queries plus a hosted-zone fee, versus the accelerator’s hourly-plus-per-GB premium. And it has no data-plane dependency on the provider’s edge: the client connects wherever DNS points, so there is no single accelerator to be an outage surface. The mature answer is frequently both: an anycast accelerator for the data path and failover, with a friendly CNAME in front of its static IP for humans and tooling.

When to pick which, as a decision table:

If your situation is… Prefer Why
Non-HTTP TCP/UDP (game, MQTT, SIP, DB, syslog) Anycast L4 accelerator DNS can’t reverse-proxy L4; failover must not depend on client cache
Long-lived / stateful connections Anycast accelerator Reconnect to a static IP steers to a healthy region in seconds
Clients that hardcode IPs or whitelist by IP Anycast (static VIP or BYOIP) A CNAME is useless to a firewall allowlist
Failover SLA in single-digit seconds Anycast accelerator No TTL/cache in the failover loop
Distant users complaining of latency/jitter Anycast accelerator Cold-potato backbone shortens and smooths the long leg
Stateless HTTP, cost-sensitive, coarse geo-steer DNS GTM Cheapest, simplest, protocol-agnostic
Precise weighted % split across regions DNS GTM (weighted records) Anycast dials are ceilings, not weights
A/B or gradual regional migration by percentage DNS GTM (or L7 accelerator rules) Fine-grained percentage control
You want zero data-plane dependency on one edge DNS GTM Client connects directly; no accelerator outage surface
Global HTTP wanting edge TLS/WAF/cache Anycast L7 (Front Door / GCP App LB) You get anycast and HTTP features at the edge

A subtle trap worth naming: DNS failover and anycast failover measure different things. A DNS health check flips a record; the client still has to re-resolve and reconnect, so your real failover is probe-detect + your TTL + slowest-resolver + client-reconnect. An anycast health check flips an edge routing decision; the client’s next packet to the same IP already goes somewhere healthy. When someone quotes you “DNS failover in 30 seconds,” that is usually the record flip, not the client-observed recovery — which is the number your SLA is actually made of.

AWS Global Accelerator: the L4 reference implementation

Global Accelerator is the cleanest expression of the pattern and the one to learn first. It gives you two static anycast IPv4 addresses from the Amazon pool (enable dual-stack to add IPv6, or bring your own prefix via BYOIP). Those addresses do not change for the life of the accelerator, which is exactly what lets you hardcode them in clients, firewall allowlists, and license servers that cannot follow a CNAME. It is a global service; its control plane lives in us-west-2.

The object model

Three objects, top to bottom: the accelerator owns the anycast IPs; a listener defines the ports and protocol those IPs accept; an endpoint group is the per-region landing zone containing endpoints (NLB, ALB, EC2 instances, or Elastic IPs). Traffic flows accelerator → listener → nearest healthy endpoint group → weighted across endpoints.

Object What it defines Key parameters Scope
Accelerator The anycast IPs and on/off IpAddressType, Enabled, BYOIP Global
Listener Ports + protocol accepted Protocol (TCP/UDP), PortRanges, ClientAffinity Per accelerator
Endpoint group Per-region landing + failover unit EndpointGroupRegion, TrafficDialPercentage, health-check config Per listener, one per region
Endpoint The actual target EndpointId, Weight, ClientIPPreservationEnabled Per endpoint group

Standing up the accelerator

Create the accelerator; it allocates the two static IPs immediately.

# Global Accelerator is global; the control plane lives in us-west-2.
aws globalaccelerator create-accelerator \
  --name edge-tcp-prod \
  --ip-address-type IPV4 \
  --enabled \
  --region us-west-2

ACCEL_ARN=$(aws globalaccelerator list-accelerators --region us-west-2 \
  --query "Accelerators[?Name=='edge-tcp-prod'].AcceleratorArn" --output text)

A listener defines the ports and protocol the anycast IPs accept. Here we take TCP 443 and a UDP range for a game protocol. SOURCE_IP affinity pins a given client to the same endpoint for the connection’s life — essential for protocols with server-side session state.

aws globalaccelerator create-listener \
  --accelerator-arn "$ACCEL_ARN" \
  --protocol TCP \
  --port-ranges FromPort=443,ToPort=443 \
  --client-affinity SOURCE_IP \
  --region us-west-2

aws globalaccelerator create-listener \
  --accelerator-arn "$ACCEL_ARN" \
  --protocol UDP \
  --port-ranges FromPort=30000,ToPort=30010 \
  --client-affinity SOURCE_IP \
  --region us-west-2

The equivalent in Terraform, which is how you should actually manage it:

resource "aws_globalaccelerator_accelerator" "edge" {
  name            = "edge-tcp-prod"
  ip_address_type = "IPV4"
  enabled         = true
}

resource "aws_globalaccelerator_listener" "tcp" {
  accelerator_arn = aws_globalaccelerator_accelerator.edge.id
  protocol        = "TCP"
  client_affinity = "SOURCE_IP"
  port_range {
    from_port = 443
    to_port   = 443
  }
}

Endpoint groups, traffic dials, and weights

An endpoint group is the per-region landing zone. Global Accelerator routes a flow to the closest healthy endpoint group, then balances across endpoints within it by weight. Two independent knobs control distribution, and confusing them is the single most common mistake:

LISTENER_ARN=$(aws globalaccelerator list-listeners --accelerator-arn "$ACCEL_ARN" \
  --region us-west-2 --query "Listeners[?Protocol=='TCP'].ListenerArn" --output text)

# Primary region, full dial, NLB endpoint. (Repeat for eu-central-1 with
# --traffic-dial-percentage 50 to cap the secondary during ramp-up.)
aws globalaccelerator create-endpoint-group \
  --listener-arn "$LISTENER_ARN" \
  --endpoint-group-region us-east-1 \
  --traffic-dial-percentage 100 \
  --endpoint-configurations '[{"EndpointId":"arn:aws:elasticloadbalancing:us-east-1:111122223333:loadbalancer/net/prod-nlb/abc123","Weight":128}]' \
  --health-check-port 443 --health-check-protocol TCP \
  --health-check-interval-seconds 10 --threshold-count 3 \
  --region us-west-2

The knobs, restated so you never confuse them again:

Knob Scope Range What it does What it does NOT do
Traffic dial Per endpoint group (region) 0–100 Caps admitted traffic; overflow spills to next-nearest group Route traffic to another region; act as a cross-region weight
Endpoint weight Per endpoint in a group 0–255 Relative share within the group Affect which region a flow lands in
Client affinity Per listener NONE / SOURCE_IP Stickiness of a client to an endpoint Preserve the client IP at the origin
Client-IP preservation Per endpoint on/off Backend sees real client IP Change stickiness or routing

Cross-region weighting at L4 is not what dials are for. If you want 70/30 across two regions for capacity reasons, do not set dials to 70 and 30 — that just caps both, and clients near each region still hit their local one first. Precise percentage splits across regions independent of geography fight the design; if you truly need them, that is a signal DNS weighted records (or an L7 rule) is the right layer for that slice of traffic.

Health checks and the failover clock

Failover speed is health-check-interval-seconds × threshold-count, plus a few seconds of propagation. With a 10-second interval and a threshold of 3, an endpoint is declared unhealthy roughly 30 seconds after it stops responding, and new flows immediately route to the next-best group. The minimum interval is 10 seconds and the threshold range is 1–10, so the practical floor is about 10–30 seconds.

For ALB endpoints, Global Accelerator does not run its own probe — it inherits the ALB’s target-group health, which is correct because the ALB already knows real backend state. For NLB, EC2, and EIP endpoints, the accelerator runs the TCP/HTTP/HTTPS check you configured.

Endpoint type Health source Client-IP preservation Best for
NLB (internet-facing) Accelerator’s own probe Supported L4 fan-out, millions of flows, preserved IP
NLB (internal) Accelerator’s own probe Not supported Private landing without preservation
ALB (internet-facing) Inherited target-group health Supported (via ALB) L7 routing/TLS/WAF behind a static anycast IP
EC2 instance Accelerator’s own probe Supported Simple/single-instance; no intra-region balancing
Elastic IP (EIP) Accelerator’s own probe Depends on target Legacy/pinned targets

Client affinity and source-IP preservation

Two distinct concerns, both critical at L4. Client affinity controls stickiness: NONE hashes the 5-tuple (source IP, source port, dest IP, dest port, protocol) so one client’s connections may land on different endpoints; SOURCE_IP hashes only on source and destination IP, pinning all of a client’s flows to one endpoint — which you want for any protocol holding per-client server state. Source-IP preservation controls what address your application sees: enable it and the backend sees the real client IP; disable it and it sees a Global Accelerator edge IP. Preservation is what keeps origin-side security groups, geo-filtering, and audit logging working.

# Preserve client IP on the endpoint (per-endpoint flag).
aws globalaccelerator update-endpoint-group \
  --endpoint-group-arn "$EG_ARN" \
  --endpoint-configurations '[{"EndpointId":"i-0abc123def456","Weight":128,"ClientIPPreservationEnabled":true}]' \
  --region us-west-2

Client-IP preservation has hard constraints. It is supported for internet-facing NLB, EC2-instance, and ALB endpoints, but not for internal NLBs. Critically, when preservation is on, the endpoint’s security group must allow the client’s IP (and the Global Accelerator managed prefix for health checks, referenced via com.amazonaws.global.globalaccelerator), not an edge address. Get this wrong and traffic flows but health checks fail, or vice versa — validate both paths before you trust it.

Azure: Front Door for HTTP, Cross-region Load Balancer for raw L4

Azure splits the pattern across two products, and choosing between them is a protocol decision. Azure Front Door (Standard/Premium) is the L7 anycast accelerator: a global anycast entry that terminates HTTP/S at the edge, adds TLS, WAF, caching, and routing, then rides Microsoft’s backbone to origins. Azure Cross-region Load Balancer is the L4 anycast accelerator: a global anycast frontend that forwards TCP/UDP to regional Standard Load Balancers, preserving the protocol and the client IP. If your workload is HTTP and wants edge features, use Front Door; if it is non-HTTP TCP/UDP, use the Cross-region Load Balancer.

Product Layer Anycast entry Terminates or forwards Client-IP behaviour Best for
Front Door Standard/Premium L7 (HTTP/S) Global anycast VIP Terminates HTTP; new backbone connection X-Forwarded-For header carries client IP Global sites/APIs wanting edge TLS/WAF/cache
Cross-region Load Balancer L4 (TCP/UDP) Global anycast frontend IP Forwards L4 to regional LBs Client IP preserved to regional LB/backend Non-HTTP TCP/UDP, static global IP, failover
Traffic Manager DNS (any) N/A (returns an address) N/A — DNS steering Direct client connection Coarse geo/priority/weighted steering, any protocol
Standard Load Balancer (regional) L4 Regional public IP Forwards L4 in-region Client IP preserved The per-region backend the cross-region LB fronts

Cross-region Load Balancer: the L4 anycast frontend

The Cross-region Load Balancer places a single global static anycast IP in front of multiple regional Standard Load Balancers. A client connects to the global IP, enters at the nearest Microsoft edge, and is forwarded over the backbone to the closest available regional load balancer; the client IP is preserved end to end. It is the closest Azure analogue to Global Accelerator for raw L4. Its backend pool is regional load balancers, not VMs directly — so you build a healthy Standard LB per region first, then front them globally.

# 1) A regional Standard LB already exists per region (e.g. lb-eastus, lb-westeurope),
#    each with its own frontend, backend pool, health probe, and rules.

# 2) Create the cross-region (global) load balancer.
az network cross-region-lb create \
  --resource-group rg-global-l4 \
  --name xlb-global \
  --frontend-ip-name fe-anycast \
  --backend-pool-name pool-regional-lbs

# 3) Add each regional LB's frontend IP into the global backend pool.
az network cross-region-lb address-pool address add \
  --resource-group rg-global-l4 \
  --lb-name xlb-global \
  --pool-name pool-regional-lbs \
  --name eastus-lb \
  --frontend-ip-address $(az network lb frontend-ip show \
      -g rg-eastus --lb-name lb-eastus -n fe --query privateIpAddress -o tsv)

# 4) A load-balancing rule ties the global frontend port to the pool.
az network cross-region-lb rule create \
  --resource-group rg-global-l4 \
  --lb-name xlb-global \
  --name rule-tcp443 \
  --frontend-ip-name fe-anycast \
  --backend-pool-name pool-regional-lbs \
  --protocol Tcp --frontend-port 443 --backend-port 443

Key properties to internalise: the global frontend IP is a static anycast address you can hardcode; home-region failover is automatic — if the nearest regional LB is unhealthy, traffic goes to the next-closest healthy region; and because it is L4 passthrough, the client IP is preserved to the regional LB and its backends, so your NSGs and app-level logging see the real source. The Cross-region LB floats on top of regional LBs, so any protocol and port your Standard LB supports (TCP and UDP) is supported globally.

Front Door: the L7 anycast accelerator

For HTTP, Front Door is the richer choice because it terminates at the edge and adds features you cannot get from L4 forwarding. It announces an anycast VIP from Microsoft’s global edge, terminates TLS, applies WAF and caching, and routes to origins over the backbone with fast, health-based origin failover. You trade L4 transparency (the origin sees Front Door, with the client IP in X-Forwarded-For) for edge TLS/WAF/cache and header-based routing.

# Front Door Standard/Premium: profile, endpoint (anycast host), origin group, origin, route.
az afd profile create -g rg-fd -n fd-prod --sku Premium_AzureFrontDoor

az afd endpoint create -g rg-fd --profile-name fd-prod \
  --endpoint-name app --enabled-state Enabled

az afd origin-group create -g rg-fd --profile-name fd-prod \
  --origin-group-name og-app \
  --probe-request-type HEAD --probe-protocol Https \
  --probe-interval-in-seconds 30 --probe-path /healthz \
  --sample-size 4 --successful-samples-required 3 --additional-latency-in-milliseconds 50

az afd origin create -g rg-fd --profile-name fd-prod \
  --origin-group-name og-app --origin-name eastus \
  --host-name app-eastus.example.com --origin-host-header app-eastus.example.com \
  --priority 1 --weight 1000 --enabled-state Enabled --http-port 80 --https-port 443

The priority/weight model on Front Door origins is your steering: priority groups origins into failover tiers (lower number = preferred; failover to the next priority when all in a tier are unhealthy), and weight splits load among origins at the same priority. That gives Front Door something anycast L4 lacks — a genuine weighted split and explicit failover ordering — because it is a full L7 proxy making a per-request decision, not an L4 forwarder making a per-flow one.

Azure decision, distilled:

If your workload is… Use Because
HTTP/S, wants edge TLS/WAF/cache, header routing Front Door L7 termination adds edge features; weighted+priority origins
Non-HTTP TCP/UDP, needs static global IP + client-IP preserve Cross-region Load Balancer L4 passthrough over backbone; preserves source IP
Any protocol, coarse geo/priority steering, lowest cost Traffic Manager DNS steering, protocol-agnostic, cheap
HTTP that also needs raw TCP for some ports Front Door (HTTP) + Cross-region LB (TCP) Two entries; pick per protocol

Google Cloud: global external load balancing on Premium Tier

Google’s model is different in shape but identical in spirit, and it hinges on Network Service Tiers. On Premium Tier (the default), a global external load balancer gives you a single global anycast IP; client traffic enters Google’s network at the PoP closest to the client (cold-potato) and rides Google’s private backbone to the nearest healthy backend, wherever it is in the world. On Standard Tier, the IP is regional and traffic uses the public internet to reach the region — cheaper, but you lose the global anycast and the backbone onramp. For anycast-accelerator behaviour, you want Premium Tier.

Google further splits by layer. The global external Application Load Balancer is L7 (HTTP/S) — it terminates HTTP at the edge (Google Front Ends), adds Cloud CDN, Cloud Armor (WAF), and URL-map routing, and is the analogue of Front Door / GCP’s HTTP anycast. The global external Network Load Balancer (and passthrough variants) operate at L4 for TCP/UDP. The unifying concept is the backend service: a global backend service references backends in multiple regions, each with a health check, and Google’s global LB steers to the closest healthy one and fails over automatically.

GCP construct Layer Tier for global anycast Terminates/forwards Adds at edge
Global external Application LB L7 (HTTP/S) Premium Terminates HTTP (GFEs) Cloud CDN, Cloud Armor, URL maps, TLS
Global external Network LB (proxy) L4 (TCP/SSL) Premium Terminates/proxies TCP/SSL SSL offload (SSL proxy), global reach
External Network LB (passthrough) L4 (TCP/UDP) Regional (Standard/Premium) Forwards L4, preserves IP Regional; not global anycast
Cloud DNS routing policies DNS (any) N/A N/A — DNS steering Geo/weighted/failover answers

A minimal global external Application LB with backends in two regions, showing the backbone-onramp behaviour on Premium Tier:

# A global anycast IP on Premium Tier — clients enter at the nearest Google PoP.
gcloud compute addresses create anycast-vip --global --network-tier=PREMIUM

# Health check drives failover between regional backends.
gcloud compute health-checks create http hc-app \
  --port=80 --request-path=/healthz --check-interval=10s \
  --timeout=5s --healthy-threshold=2 --unhealthy-threshold=3 --global

# A GLOBAL backend service referencing regional backends (backbone routing + failover).
gcloud compute backend-services create bes-app \
  --global --protocol=HTTP --health-checks=hc-app --load-balancing-scheme=EXTERNAL_MANAGED

gcloud compute backend-services add-backend bes-app --global \
  --instance-group=ig-us --instance-group-zone=us-central1-a
gcloud compute backend-services add-backend bes-app --global \
  --instance-group=ig-eu --instance-group-zone=europe-west1-b

# URL map → target proxy → global forwarding rule pins the anycast VIP to the service.
gcloud compute url-maps create um-app --default-service bes-app
gcloud compute target-http-proxies create tp-app --url-map=um-app
gcloud compute forwarding-rules create fr-app --global \
  --address=anycast-vip --target-http-proxy=tp-app --ports=80 --network-tier=PREMIUM

The behaviour to internalise: because the backend service is global, Google routes each new client to the closest healthy backend region over the backbone, and if a region’s backends fail their health check, traffic shifts to another region automatically — the same seconds-scale, no-DNS failover you get from Global Accelerator, expressed through Google’s backend-service model. For client IP: the L7 Application LB terminates HTTP and passes the client IP in X-Forwarded-For (GFEs are the source to your backend); the passthrough Network LB preserves the client IP but is regional, so a global passthrough-with-preserved-IP story on GCP means a proxy LB (IP in a header) or careful regional design. This is the one place GCP’s split differs meaningfully from AWS’s single L4 product.

The Premium-versus-Standard Tier choice, because it is the anycast decision on GCP:

Attribute Premium Tier Standard Tier
IP scope Global anycast Regional
Client onramp Nearest Google PoP (cold-potato) Public internet to the region
Backbone usage Google backbone edge-to-region Mostly public internet
Global LB support Yes (global backend service) No (regional LBs only)
Latency/jitter on long leg Lower, tighter (engineered) Whatever transit gives
Cost Higher egress pricing Lower egress pricing
Use when Global users, failover, quality Regional/cost-sensitive, single-region

Cross-cloud comparison: same pattern, three dialects

Now hold the three side by side. The pattern is identical — anycast IP, edge onramp, backbone, health-based regional failover — but the product boundaries and the L4/L7 split differ, and knowing the mapping saves you from asking “what’s the GCP equivalent of a traffic dial?” mid-design.

Capability AWS Azure GCP
L4 anycast accelerator (TCP/UDP) Global Accelerator Cross-region Load Balancer Global ext. Network LB (proxy) / regional passthrough
L7 anycast accelerator (HTTP) CloudFront / GA→ALB Front Door Std/Premium Global ext. Application LB
Static anycast IP count 2 (IPv4) + optional IPv6 1 global frontend IP 1 global IP (Premium)
BYOIP anycast Yes (BYOIP) Limited Yes (BYOIP)
Per-region unit Endpoint group Regional LB in global pool Regional backend in global backend service
Cross-region weighting Awkward (dials are ceilings) Weighted origins (Front Door L7) Backend capacity/weights
Drain a region Traffic dial → 0 Remove from pool / drain Set capacity 0 / remove backend
Client-IP preservation (L4) Per-endpoint flag (some limits) Preserved (passthrough) Preserved on passthrough (regional)
Health-check floor ~10s interval, 1–10 threshold Probe-driven (LB probes) ~configurable interval + thresholds
Failover trigger Endpoint-group health Regional LB health Backend-service health
Global tier gate (always global) (always global) Premium Tier required

The steering-model comparison is the one that trips people, because AWS, Azure, and GCP express “how much traffic goes where” differently:

Steering intent AWS Global Accelerator Azure Front Door (L7) GCP global LB
Nearest healthy region Automatic (endpoint-group proximity) Automatic (edge picks + priority) Automatic (backend-service proximity)
Cap a region (drain/ramp) Traffic dial 0–100 Remove/drain origin Backend capacity / maxUtilization
Weighted % across regions Not native at L4 Origin weight (same priority) Backend capacityScaler / weights
Explicit failover order Health-based only Origin priority tiers Backend health + failover policy
Remove one endpoint Weight 0 Disable origin Remove backend

Read this table as a warning: only the L7 accelerators (Front Door, GCP App LB) give you a clean weighted split, because they make per-request decisions. AWS Global Accelerator, being L4, steers per-flow to the nearest healthy region and uses dials as ceilings — so “exactly 20% of global traffic to the new region regardless of geography” wants an L7 accelerator or DNS weighting, on any cloud.

Health-check tuning is your failover-budget dial, and the parameters differ per cloud even though the maths is the same (detect ≈ interval × unhealthy-threshold). Set them to a target detection time, then remember client reconnect is added on top:

Parameter AWS Global Accelerator Azure (FD / LB probe) GCP health check Effect of tightening
Probe interval 10s (fixed minimum) Configurable (FD interval / LB probe) Configurable (--check-interval) Faster detect; more probe load
Unhealthy threshold 1–10 (threshold-count) Sample/failure counts --unhealthy-threshold Fewer misses tolerated → faster + noisier
Healthy threshold (implicit) successful-samples-required --healthy-threshold Faster recovery; risk of flapping
Probe protocol TCP / HTTP / HTTPS HTTP(S) / TCP HTTP(S) / TCP / gRPC Must match a real readiness signal
Practical detect floor ~30s (10s × 3) seconds (tunable) seconds (tunable) Below this you invite false evictions

And the decision most people actually need — given a region count and a failover budget, what should I reach for — as a single matrix:

Regions Failover budget Protocol Recommended approach
1 any any No accelerator needed for failover; use one only for static IP / edge onramp
2+ minutes OK stateless HTTP DNS GTM (cheapest) or L7 accelerator if you want edge features
2+ seconds non-HTTP TCP/UDP Anycast L4 accelerator (GA / Cross-region LB / GCP L4)
2+ seconds HTTP wanting edge TLS/WAF/cache Anycast L7 accelerator (Front Door / GCP App LB / CloudFront)
2+ seconds + precise % split HTTP L7 accelerator (weighted origins) — not L4
2+ seconds + static IP for allowlists any TCP/UDP Anycast L4 accelerator (static VIP) or BYOIP
3+ seconds, quality-sensitive real-time UDP (game/media) Anycast L4 + reconnect-to-static-IP client design

Ports, protocols, and what each product actually forwards

“Anycast accelerator” is not one capability; each product forwards a specific set of protocols and ports, and picking the wrong one for your protocol is a day-one failure. Enumerate before you commit.

Product Protocols Port model Non-HTTP? UDP? Notable limit
AWS Global Accelerator TCP, UDP Port ranges per listener Yes Yes Listener count and port-range caps per accelerator
AWS GA → ALB endpoint HTTP/S (via ALB) ALB listener ports Via ALB rules No (ALB) ALB is HTTP/S only
Azure Cross-region LB TCP, UDP Frontend/backend port rules Yes Yes Backend pool is regional LBs, not VMs
Azure Front Door HTTP, HTTPS 80/443 (+ custom via rules) No (HTTP only) No L7 only; not for raw TCP/UDP
GCP global ext. App LB HTTP, HTTPS, HTTP/2, gRPC 80/443/custom HTTP-family No L7; needs Premium for global
GCP global ext. Network LB (proxy) TCP, SSL Configured ports TCP/SSL No (proxy) SSL proxy is TCP-based
GCP passthrough Network LB TCP, UDP, ESP/ICMP Ports/protocol Yes Yes Regional, not global anycast

The decision that follows from this table is blunt: if your protocol is HTTP/S, you have the richest choice (any L7 accelerator, plus L4 if you want raw passthrough). If it is non-HTTP TCP, you want an L4 product (GA, Cross-region LB, GCP proxy/passthrough). If it is UDP — game traffic, QUIC-on-your-own-terms, syslog, DNS, media — your options narrow to the true L4 forwarders: AWS Global Accelerator, Azure Cross-region Load Balancer, and GCP passthrough (regional). UDP is where DNS GTM and L7 accelerators both drop out, and where an anycast L4 accelerator is often the only clean answer.

A protocol-to-product cheat sheet you can paste into a design doc:

Your protocol AWS Azure GCP
Global HTTP/S API or site CloudFront / GA→ALB Front Door Global ext. App LB (Premium)
gRPC / HTTP/2 GA→ALB (or ALB gRPC) Front Door (limited) / App Gateway Global ext. App LB
Raw TCP (DB, custom binary) Global Accelerator → NLB Cross-region LB Global ext. Network LB (proxy)
UDP (game, SIP/RTP, syslog) Global Accelerator → NLB Cross-region LB Passthrough Network LB (regional)
MQTT/AMQP broker (TCP) Global Accelerator → NLB Cross-region LB Global ext. Network LB (proxy)
Static IP for firewall allowlist GA static IPs / BYOIP Cross-region LB global IP Global IP / BYOIP (Premium)

Architecture at a glance

Picture the path a distant client’s packet actually takes, because the whole value proposition lives in that path. A client in Frankfurt opens a connection to your service, whose public face is a single static anycast IP — one address announced by BGP from dozens of the cloud provider’s PoPs worldwide. The client’s ISP routes that first packet, by ordinary IP routing, to the nearest announcement of the prefix: the Frankfurt edge. The client did not choose a region, consult DNS a second time, or know where your application runs; it simply sent a packet to an IP, and standard routing delivered it to the closest door.

At that Frankfurt PoP the accelerator takes over. For an L4 product (AWS Global Accelerator, Azure Cross-region LB, GCP passthrough/proxy) it forwards the TCP/UDP flow, preserving the protocol and — if you asked — the client’s real source IP. For an L7 product (Front Door, GCP global Application LB) it terminates the HTTP/TLS session at the edge, applies WAF and caching, then opens a fresh backbone connection to origin. Either way, the packet now leaves the public internet and rides the provider’s private, congestion-managed backbone. This is the cold-potato onramp: the client used only a short public hop to reach the edge; the long, quality-sensitive leg across the continent runs on an engineered network with lower and tighter latency than any transit path.

The backbone carries the flow to the closest healthy regional landing zone — an endpoint group (AWS), a regional load balancer in the global pool (Azure), or a regional backend in the global backend service (GCP) — which does the per-target work across the actual servers. Health flows up: each server’s health informs the regional LB, which (for L7) informs the accelerator’s routing decision. Continuously, the accelerator probes each region; the moment eu-central-1 fails its check for the threshold number of intervals, the edge stops sending it new flows and routes them to the next-best region — in seconds, no DNS change and no client cache to expire. If the client’s live flow was pinned to the failed region it resets, and its reconnect to the same anycast IP lands somewhere healthy. That is the entire architecture: one static IP at the edge, backbone in the middle, health-driven regional selection at the far end, and a failover clock measured in seconds because DNS was never in the loop.

Real-world scenario

Nimbus Arena is a multiplayer game studio running authoritative UDP game servers in us-east-1 and eu-central-1 behind Route 53 latency records. Peak concurrency is around 120,000 players; a match lasts 20–40 minutes; the protocol is UDP with server-authoritative per-match state, so an HTTP-based global balancer is a non-starter. The platform team is six engineers, and the previous quarter’s reliability review flagged “regional failover” as their worst SLO.

The incident that forced the change was a partial us-east-1 AZ impairment on a Saturday evening. Players already mid-match kept their UDP sessions pinned to the failing region because their clients had cached the A record at match-join and the game SDK’s resolver TTL was effectively ignored — the client held the IP for the life of the match. Sessions degraded for two to three minutes, well past the point players rage-quit, even though the EU region was healthy the whole time. Route 53’s health check had flipped the record within 30 seconds, but that did nothing for the hundreds of thousands of clients that already had the old address and would not re-resolve until the match ended. The DNS “failover” was real and fast — and completely irrelevant to the clients in flight.

They moved the public entry to AWS Global Accelerator. Each region got an endpoint group fronting an internal NLB pool of game servers; the listener used UDP with SOURCE_IP affinity so a player’s packets pinned to one server for the match, and health checks ran at a 10-second interval with threshold 3 (a ~30-second detection floor). The client SDK already reconnected to the same address on packet-loss timeout — and because that address was now a static anycast IP, reconnects were steered to a healthy region in seconds with no DNS in the path. They flipped the new region’s traffic dial up gradually to validate capacity before taking full load.

The measured result: client-observed regional failover dropped from 2–3 minutes to under 30 seconds; mid-match disconnects during the next regional event were a brief reconnect rather than a multi-minute outage; and median RTT for distant players fell by 18–24ms because the long leg now rode the AWS backbone instead of public transit, with the jitter (RTT stddev) falling even more sharply — which for a real-time game mattered more than the mean. The one behaviour they documented loudly for the on-call team: in-flight UDP flows on the failed servers still reset — anycast protects the reconnect, not the connection that was live on the dead box. They kept Route 53 in front of the accelerator’s static IPs as a friendly hostname for tooling and support, but the failover path no longer touched DNS at all.

The before/after, because the contrast is the lesson:

Dimension Before (Route 53 latency) After (Global Accelerator)
Client-observed failover 2–3 minutes (client cached A record) < 30 seconds (reconnect to static IP)
Failover mechanism DNS record flip (ignored by in-flight clients) Edge health check, no client cache
Distant-player median RTT baseline −18 to −24ms (backbone long leg)
Jitter (RTT stddev) baseline sharply lower (engineered path)
Static IP for allowlists No (clients resolve a name) Yes (two anycast IPs)
In-flight flow on failure Degrades for minutes Resets → fast reconnect
DNS in failover path Yes (the problem) No

Advantages and disadvantages

The anycast-accelerator model both fixes a specific class of problem and introduces its own costs and dependencies. Weigh it honestly.

Advantages Disadvantages
Static, hardcodable IP survives region moves — perfect for firewall allowlists, license servers, IoT A per-hour + per-GB premium over “just DNS”; the bill is real for high-throughput UDP
Failover in seconds via edge health checks — no DNS TTL, no client cache in the loop Protects the reconnect, not in-flight flows — the live connection on a failed box still resets
Cold-potato backbone shortens and smooths the long leg — lower mean RTT and lower jitter You depend on the provider’s edge/backbone as a data-plane surface (though it is highly available)
Works for non-HTTP TCP and UDP where DNS GTM and L7 proxies can’t reverse-proxy Precise cross-region % splits are awkward at L4 (dials are ceilings, not weights)
Client-IP preservation keeps origin security groups, geo-filtering, and audit intact Preservation has hard constraints (internal NLBs, boundary cases) that must be validated both ways
Decouples client entry from origin — add/drain/lose a region invisibly to clients More moving parts than a DNS record; another system to monitor, IaC, and reason about
One global entry to observe, alert on, and secure (WAF at L7 variants) L7 variants terminate the connection — origin sees the edge, client IP moves to a header

The model is right when the protocol is non-HTTP or stateful, when you need a static IP, or when failover must be measured in seconds. It is over-engineering when your workload is stateless HTTP with a relaxed failover budget and cost sensitivity — there, DNS GTM (or plain regional deployment) is simpler and cheaper. The disadvantages are all manageable, but only if you know they exist: the reconnect-not-in-flight behaviour is the one that surprises teams in their first regional event, and the client-IP-preservation constraints are the one that produces “traffic works but health checks fail” tickets.

Hands-on lab

Stand up a minimal AWS Global Accelerator in front of a single-region NLB, confirm the anycast IPs, prove the latency behaviour, and force a failover — all with real commands and validation. (Costs a few dollars for the hours it runs; tear down at the end.)

Step 1 — Variables.

export AWS_PAGER=""
REGION_A=us-east-1
GA_REGION=us-west-2          # Global Accelerator control plane
NAME=lab-ga

Step 2 — Create the accelerator and capture its ARN and static IPs.

aws globalaccelerator create-accelerator --name $NAME --ip-address-type IPV4 --enabled --region $GA_REGION
ACCEL_ARN=$(aws globalaccelerator list-accelerators --region $GA_REGION \
  --query "Accelerators[?Name=='$NAME'].AcceleratorArn" --output text)

# Wait for provisioning, then read the two anycast IPs.
aws globalaccelerator describe-accelerator --accelerator-arn "$ACCEL_ARN" --region $GA_REGION \
  --query "Accelerator.IpSets[0].IpAddresses"

Expected: two IPv4 addresses (e.g. ["75.2.x.x","99.83.y.y"]). These are your static anycast IPs.

Step 3 — Create a TCP listener on 443 with source-IP affinity.

aws globalaccelerator create-listener --accelerator-arn "$ACCEL_ARN" \
  --protocol TCP --port-ranges FromPort=443,ToPort=443 --client-affinity SOURCE_IP --region $GA_REGION
LISTENER_ARN=$(aws globalaccelerator list-listeners --accelerator-arn "$ACCEL_ARN" --region $GA_REGION \
  --query "Listeners[0].ListenerArn" --output text)

Step 4 — Add an endpoint group in us-east-1 pointing at an existing NLB. (Use the ARN of an internet-facing NLB you already have, or create one first.)

NLB_ARN=$(aws elbv2 describe-load-balancers --region $REGION_A \
  --query "LoadBalancers[?Type=='network'].LoadBalancerArn | [0]" --output text)

aws globalaccelerator create-endpoint-group --listener-arn "$LISTENER_ARN" \
  --endpoint-group-region $REGION_A \
  --endpoint-configurations "[{\"EndpointId\":\"$NLB_ARN\",\"Weight\":128}]" \
  --health-check-port 443 --health-check-protocol TCP \
  --health-check-interval-seconds 10 --threshold-count 3 --region $GA_REGION

EG_ARN=$(aws globalaccelerator list-endpoint-groups --listener-arn "$LISTENER_ARN" --region $GA_REGION \
  --query "EndpointGroups[0].EndpointGroupArn" --output text)

Step 5 — Confirm endpoint health.

aws globalaccelerator describe-endpoint-group --endpoint-group-arn "$EG_ARN" --region $GA_REGION \
  --query "EndpointGroup.EndpointDescriptions[].{Id:EndpointId,Health:HealthState,Reason:HealthReason}"

Expected: the NLB endpoint reports HEALTHY. If it is UNHEALTHY, the NLB’s target group has no healthy targets, or the security group blocks the Global Accelerator health-check prefix — fix that before proceeding.

Step 6 — Prove the anycast path from a distant client. From a machine far from us-east-1, compare RTT to the accelerator IP against RTT to the NLB’s regional DNS name.

ACCEL_IP=75.2.0.1   # one of your two static IPs
ping -c 20 "$ACCEL_IP" | tail -3
ping -c 20 <your-nlb>.elb.us-east-1.amazonaws.com | tail -3

Expected on a transcontinental client: the anycast path shows a lower and tighter RTT (lower mean and lower mdev/stddev) because the long leg rides the backbone. If they are identical, your client is adjacent to us-east-1 — test from a genuinely distant location.

Step 7 — Force a failover and time it. Break the endpoint honestly (stop the NLB’s targets, or block the health-check port in the target security group), then watch health flip.

watch -n 5 'aws globalaccelerator describe-endpoint-group --endpoint-group-arn "'$EG_ARN'" \
  --region '$GA_REGION' --query "EndpointGroup.EndpointDescriptions[].HealthState" --output text'

Expected: HEALTHY → UNHEALTHY within ~30 seconds (10s interval × threshold 3). With a second endpoint group in another region, a client reconnecting to the same anycast IP would land there. Time the client-observed recovery, not just the console flip — that end-to-end number is what an SLA is made of.

Validation checklist.

Step What you did What it proves
2 Created accelerator, read two IPs The static anycast IPs exist and are hardcodable
3 TCP listener with SOURCE_IP The port/protocol contract and stickiness are explicit
4–5 Endpoint group + health The per-region landing zone and health source work
6 RTT comparison The cold-potato backbone win is measurable (mean + jitter)
7 Forced failover Detection time ≈ interval × threshold; DNS not involved

Teardown (delete children before the accelerator; disable it first).

aws globalaccelerator delete-endpoint-group --endpoint-group-arn "$EG_ARN" --region $GA_REGION
aws globalaccelerator delete-listener --listener-arn "$LISTENER_ARN" --region $GA_REGION
aws globalaccelerator update-accelerator --accelerator-arn "$ACCEL_ARN" --no-enabled --region $GA_REGION
aws globalaccelerator delete-accelerator --accelerator-arn "$ACCEL_ARN" --region $GA_REGION

Common mistakes & troubleshooting

The failure modes are specific and repeat across every anycast deployment. Scan the table, then read the detail for whichever row matches.

# Symptom Root cause Confirm (exact command / path) Fix
1 Traffic flows but the origin sees an edge IP, not the client Client-IP preservation off (or unsupported endpoint) describe-endpoint-groupClientIPPreservationEnabled; check logs’ source IP Enable per-endpoint preservation; use a supported endpoint type
2 Traffic works, health checks fail (endpoint UNHEALTHY) Security group allows client IPs but not the GA health-check prefix Endpoint SG rules vs com.amazonaws.global.globalaccelerator prefix Allow the managed health-check prefix on the health-check port
3 Set traffic dials to 70/30, split didn’t happen Dials are per-region ceilings, not cross-region weights describe-endpoint-groupTrafficDialPercentage; observe flows Use geo-nearest + dials for drain/ramp; use L7/DNS for true % split
4 Failover “took minutes” despite health checks You measured DNS failover, or client didn’t reconnect to the static IP Time client-observed recovery, not the record/console flip Ensure client reconnects to the same anycast IP on reset
5 New container/server deploy: connections refused via accelerator Backend bound 127.0.0.1, not 0.0.0.0 On host: ss -ltnp shows loopback bind only Bind 0.0.0.0:<port> so the regional LB/edge can reach it
6 UDP works locally, times out through the accelerator Wrong listener protocol/port range, or a firewall dropping UDP list-listeners → protocol/port; check NSG/SG for UDP allow Match listener protocol=UDP and the exact port range; allow UDP
7 One region takes all traffic; the other stays cold Both regions healthy, clients are simply nearer one CloudWatch NewFlowCount per endpoint group Expected for geo-nearest; use dials only to force spillover
8 Client sticks to a dead server after failover SOURCE_IP affinity pinned it; the pinned box is gone list-listenersClientAffinity; observe reconnect target Affinity is correct; the reconnect re-steers — design client to reconnect
9 HTTPS via L7 accelerator returns cert/SNI errors Origin host header / SNI mismatch at the edge proxy Front Door origin host header; GCP host rules Set correct origin host header / SNI; align certs
10 GCP LB isn’t global; clients hit the public internet Deployed on Standard Tier (regional IP) gcloud compute addresses describe --global shows tier Recreate the address/forwarding rule on Premium Tier
11 Cross-region LB (Azure) has no backends healthy Regional Standard LBs not added, or their probes failing az network cross-region-lb address-pool ... list; regional probe health Add each regional LB frontend to the global pool; fix regional probes
12 Static IP changed / clients broke after a rebuild You deleted and recreated the accelerator (new IPs) Compare current IpSets to the allowlisted IPs Never recreate; or use BYOIP so the prefix is portable
13 Costs spiked unexpectedly on a high-throughput UDP app Per-GB data-transfer premium on all accelerated bytes Cost Explorer by GA usage type; bytes-processed metrics Right-size; confirm the latency/failover win justifies the per-GB cost
14 Behind-the-edge WAF blocks legitimate game/API traffic L7 accelerator applied WAF to a non-HTTP or sensitive path WAF logs; matched rule IDs Use L4 for non-HTTP; tune/scope WAF rules for L7 paths

The expanded reasoning for the ones that bite hardest:

Rows 1 & 2 — the client-IP preservation pair are the classic “half-working” state. Preservation off means the backend sees a GA edge address, silently breaking any origin security-group rule, geo-filter, or audit keyed on the client IP. Turn it on per endpoint — but then the security group must allow the client’s IP on the service port and the GA managed prefix (com.amazonaws.global.globalaccelerator) on the health-check port, because health checks come from the managed prefix, not from clients. Get one right and the other wrong and you land in symptom 1 or 2. Validate both paths before you trust it.

Rows 3 & 7 — dials are not weights. A dial of 50 on eu-central-1 means “admit at most 50% of what would arrive here; spill the rest to the next-nearest group” — clients near EU still hit EU first. One region taking almost everything (symptom 7) is usually correct geo-nearest behaviour, not a bug. Use dials to drain (0) or ramp (start at 25, watch, raise), never to enforce a percentage.

Rows 4 & 8 — failover measures the reconnect. When someone reports “failover took two minutes,” ask what they measured: a DNS record flip or a console health state is not client-observed recovery. The real number is detection (interval × threshold) + edge re-route (seconds) + the client reconnecting to the same IP. A client that caches the address and never reconnects gives you the two-minute number even with a perfect accelerator — the fix is always client behaviour.

Row 10 — GCP’s Premium-Tier gate. “My global load balancer isn’t global” almost always means the IP or forwarding rule was created on Standard Tier (regional IP, public transport). Confirm with gcloud compute addresses describe <name> --global, then recreate on PREMIUM. This is the most common GCP-specific miss because Standard Tier is cheaper and easy to select by accident.

Best practices

Security notes

Cost & sizing

The bill has two shapes depending on layer, and the per-GB component surprises high-throughput teams. AWS Global Accelerator charges a fixed hourly fee per accelerator plus a data-transfer-premium per GB on all accelerated traffic (on top of normal egress) — so a chatty UDP game at hundreds of Mbps sustained pays a meaningful premium that a low-throughput API does not. Azure Front Door prices by request + data transfer + WAF rules; the Cross-region Load Balancer prices like a load balancer (rule-hours + processed data). GCP’s global LB adds Premium-Tier egress pricing (higher than Standard) plus forwarding-rule and data-processing charges. In every case, the premium buys you the backbone and the fast failover — so the sizing question is always “is the latency/jitter/failover win worth the per-GB premium for this traffic volume?”

Cost driver AWS Global Accelerator Azure (Front Door / Cross-region LB) GCP global LB
Fixed component Per-accelerator hour FD: base + rules / LB: rule-hours Forwarding-rule + LB hours
Variable component Per-GB data-transfer premium FD: per-request + per-GB / LB: processed GB Premium-Tier egress + processed GB
Where it stings Sustained high-throughput UDP High request volume (FD) Large egress on Premium Tier
Cheap when Low-throughput, high-value flows Cacheable HTTP (FD offloads origin) Modest egress, global users
Free-tier reality None for GA itself FD has limited free entitlements LB has no meaningful free tier

Sizing guidance, in plain terms: size the regions, not the accelerator — the accelerator scales itself; your cost lever is how much traffic you accelerate and how many regional endpoints you run. For a two-region L4 service at modest throughput, the accelerator’s fixed fee dominates and the per-GB premium is noise; for a high-bandwidth media or game workload, model the per-GB premium against your real traffic before committing, and consider whether only the latency-sensitive slice needs acceleration while bulk transfer takes a cheaper path. Keep two regions minimum so failover has somewhere to go; a single-region accelerator buys you the static IP and edge onramp but not the regional failover that is half the value.

A rough monthly picture for a two-region L4 API at low-to-moderate throughput: the accelerator’s fixed hourly fee plus a small per-GB premium is typically a modest line item next to the two regional load balancers and the compute behind them — often a few thousand rupees to low tens of thousands, dominated by traffic volume. The moment you are pushing sustained high-bandwidth UDP, the per-GB premium becomes the dominant term and deserves a spreadsheet, not a guess.

Interview & exam questions

1. What is anycast, and how does an anycast accelerator get a client onto the cloud backbone? Anycast is one IP prefix announced via BGP from many PoPs at once; ordinary IP routing delivers a client’s first packet to the nearest announcement. The accelerator terminates or forwards that flow at the edge and carries it over the provider’s private backbone to a regional endpoint — so the client uses a short public hop to the edge, then rides the engineered network the rest of the way (cold-potato onramp).

2. Why does an anycast accelerator beat DNS-based GTM for stateful L4 traffic? DNS hands out an address and never sees another packet; a client that cached the record keeps hitting a dead region until its cache expires, which you don’t control. Anycast keeps the client on a static IP that never moves, and fails over via an edge health check in seconds with no DNS TTL or client cache in the loop. For long-lived or stateful connections (game sessions, MQTT, market data), that difference is the whole ballgame.

3. Explain cold-potato versus hot-potato routing and why it matters here. Hot-potato hands traffic off to the next network as soon as possible (cheap, high latency/jitter); cold-potato keeps traffic on the provider’s backbone as long as possible, onboarding at the edge nearest the client. Anycast accelerators are cold-potato, so the quality-sensitive long leg runs on an engineered network — lower and tighter RTT (mean and jitter both improve) than public transit.

4. A traffic dial of 50 on a region — what does it do, and what does it not do? It caps admitted traffic at that region to 50% of what would arrive; overflow spills to the next-nearest endpoint group. It does not act as a cross-region weight — clients near that region still hit it first. Dials are for draining (0) and ramping a region, not for enforcing a percentage split across regions.

5. Difference between client affinity and client-IP preservation on Global Accelerator? Client affinity (NONE vs SOURCE_IP) controls stickiness — whether a client’s flows pin to one endpoint (needed for per-client server state). Client-IP preservation controls what the backend sees as the source — the real client IP versus a GA edge IP. One is about where flows land; the other is about origin-side visibility for security, geo-filtering, and audit.

6. Map the anycast-accelerator pattern to AWS, Azure, and GCP. AWS: Global Accelerator (L4) and CloudFront/GA→ALB (L7). Azure: Cross-region Load Balancer (L4) and Front Door (L7). GCP: global external Network LB (L4, proxy/passthrough) and global external Application LB (L7) — both requiring Premium Tier for global anycast. The per-region unit is an endpoint group (AWS), a regional LB in a global pool (Azure), or a regional backend in a global backend service (GCP).

7. Your UDP game fails over in “two minutes” despite 30-second health checks. Why? Almost certainly the client isn’t reconnecting to the static IP — it cached the address (or held the flow) and only re-establishes when the match ends. The accelerator detected and re-routed in ~30 seconds, but the client-observed recovery depends on the client reconnecting to the same anycast IP on reset. Fix the client behaviour, not the health check.

8. Why can’t you run a raw TCP database protocol through Azure Front Door? Front Door is an L7 HTTP/S proxy — it terminates and understands HTTP, not arbitrary TCP. For raw TCP you need an L4 forwarder: Azure Cross-region Load Balancer (or, on AWS, Global Accelerator; on GCP, a global Network LB). Matching product layer to protocol is the first design decision.

9. What breaks when client-IP preservation is enabled but the security group is wrong? You get a half-working state: either traffic flows but health checks fail (the health-check prefix isn’t allowed on the probe port), or health passes but real client traffic is blocked (the client IPs aren’t allowed on the service port). Preservation makes the backend see the client IP and the GA health-check prefix, so the security group must allow both on their respective ports.

10. On GCP, your global load balancer is behaving regionally. Most likely cause? The IP or forwarding rule was created on Standard Tier, which yields a regional IP and public-internet transport. Recreate on Premium Tier to get the global anycast VIP and the backbone onramp. Confirm with gcloud compute addresses describe <name> --global and check the network tier.

11. When is DNS-based GTM still the right tool over an anycast accelerator? When the workload is stateless HTTP with a relaxed failover budget, when you need a precise weighted percentage split across regions independent of geography, when cost sensitivity outweighs the per-GB premium, or when you specifically want no data-plane dependency on a single provider edge. DNS is protocol-agnostic and cheap; anycast is for stateful/non-HTTP/seconds-failover/static-IP needs.

12. What does anycast failover not protect, and how do you design around it? It does not migrate in-flight flows — the TCP/UDP connection live on a failed endpoint resets. Design the client to reconnect on reset/timeout to the same anycast IP, so a regional failure becomes a brief reconnect (steered to a healthy region in seconds) rather than a multi-minute outage.

These map to AWS Advanced Networking – Specialty (ANS-C01) (global accelerator, edge networking, hybrid failover), Azure AZ-700 (Network Engineer Associate) (Front Door, Load Balancer, Traffic Manager, global distribution), and Google Professional Cloud Network Engineer (global load balancing, Network Service Tiers, Cloud Armor). A compact cert mapping:

Question theme Primary cert Objective area
Anycast, cold-potato, backbone onramp ANS-C01 / GCP PCNE Edge & global connectivity design
GA listeners, endpoint groups, dials ANS-C01 Design and implement global acceleration
Front Door vs Cross-region LB vs Traffic Manager AZ-700 Design and implement traffic distribution
GCP global LB, Premium vs Standard Tier GCP PCNE Network services, load balancing
Client-IP preservation, security groups ANS-C01 / AZ-700 Secure and observe network traffic
Failover budgets, health checks, reconnect All three Resiliency and high availability

Quick check

  1. A client cached your DNS record 20 seconds ago; the region behind that record just failed. Why does an anycast accelerator recover this client faster than a DNS failover, even if both health checks flipped in the same 30 seconds?
  2. You set traffic dials to 70 and 30 on two regions expecting a 70/30 split. Traffic still lands mostly by geography. What did you misunderstand, and what should you have used?
  3. Traffic flows through your Global Accelerator, but the origin’s audit log shows a Global Accelerator edge IP instead of the real client. What single setting fixes this, and what must you then change on the security group?
  4. On GCP, your “global” external load balancer is sending distant clients over the public internet instead of the backbone. What is the most likely cause and the fix?
  5. Your UDP service has 30-second health checks, yet a regional failure degraded live matches for two minutes. Where is the two minutes coming from, and how do you fix it?

Answers

  1. Because the anycast client never has a per-region address to cache — it holds a static anycast IP that never moves, so when the edge re-routes (in ~30s), the client’s next packet to the same IP already goes somewhere healthy. The DNS client, by contrast, still has to notice the record changed, re-resolve past its cache, and reconnect, and it won’t re-resolve until its cache expires — so the record flip is irrelevant to a client already holding the old address.
  2. Traffic dials are per-region ceilings, not cross-region weights — dial 30 just caps that region and spills overflow to the next-nearest group; clients near each region still hit their local one first. For a true weighted percentage split you need an L7 accelerator (Front Door / GCP App LB origin weights) or DNS weighted records.
  3. Enable client-IP preservation on the endpoint. You must then ensure the endpoint’s security group allows the client’s IP on the service port and the Global Accelerator health-check prefix (com.amazonaws.global.globalaccelerator) on the health-check port — or you get the half-working “traffic passes, health fails” (or vice versa) state.
  4. The IP/forwarding rule was created on Standard Tier, which is a regional IP over public internet. Recreate the address and forwarding rule on Premium Tier to get the global anycast VIP and cold-potato backbone onramp; confirm with gcloud compute addresses describe <name> --global.
  5. The accelerator detected and re-routed in ~30 seconds; the extra time is the client not reconnecting — it cached the address or held the flow and only re-established when the match ended. Fix the client to reconnect on reset/timeout to the same anycast IP, turning a regional failure into a brief reconnect.

Glossary

Next steps

You can now decide between anycast and DNS GTM for a given protocol and failover budget, pick the right product on each cloud, and stand it up. Build outward:

AnycastGlobal AcceleratorFront DoorLoad BalancingAWSAzureGCPFailover
Need this built for real?

Vinod is a Senior Cloud Architect (22+ yrs) — available for Azure / AWS / GCP architecture, landing zones, and migrations.

Work with me

Comments

Keep Reading