Skip to content
BytePatterns

CloudFront vs Global Accelerator: Cache at the Edge or Route Over It

7 min readBytePatterns

CloudFront vs Global Accelerator: a caching HTTP CDN with changing edge IPs, or two static anycast IPs that proxy TCP and UDP to nearest healthy Region.

CloudFront vs Global Accelerator in one line: CloudFront is a content delivery network that answers HTTP and HTTPS requests from caches at edge locations and only goes to your origin on a miss, while Global Accelerator caches nothing: it gives your application static anycast IP addresses and carries every TCP or UDP connection from the nearest edge location over the AWS global network to a healthy regional endpoint. Both start at an AWS edge; what happens there is the whole difference. Facts are from the AWS documentation listed at the end, as of October 2026.

CloudFrontGlobal Accelerator
TrafficHTTP and HTTPS requestsany TCP or UDP connection
Addresses clients usea domain name; edge IPs chosen by CloudFronttwo static anycast IPv4 addresses (four with dual-stack)
At the edgecache lookup, TLS, per-request codeno cache; proxy to the nearest healthy endpoint

The problem it solves

Two teams hear the same advice, "put it on the edge". The first serves a web app's scripts and images to users on four continents and wants fewer slow trips to one origin in Ireland. The second runs a multiplayer game over UDP and an API whose enterprise customers allow-list IP addresses in their firewalls, and it needs a Region failure to be invisible to clients. CloudFront is the answer to the first problem and cannot carry the second; Global Accelerator answers the second and does nothing to shorten the first, because every request still reaches a server.

The intuition

CloudFront reads each request. A distribution has a domain name, and DNS hands each viewer the addresses of a nearby edge location; CloudFront picks those addresses and they change over time, which is why you point a CNAME or alias record at the distribution rather than at IPs. At the edge it terminates TLS, builds the cache key from the path and whatever headers, cookies and query strings your cache policy includes, and serves a hit from local storage. A miss goes to a regional edge cache, then to the origin. Because it understands HTTP, it can run CloudFront Functions or Lambda@Edge on a request and attach AWS WAF. Static addresses are possible, but as an opt-in: an Anycast static IP list is requested through CloudFront support, and the documentation frames it for allow-listing with network providers and for routing apex domains.

Global Accelerator moves connections. An accelerator gets two static IPv4 addresses, anycast from the AWS edge network, and keeps them as long as it exists, even while disabled; you can also bring your own range. A client's packets enter the AWS network at the closest edge, where Global Accelerator terminates the TCP connection and opens a new one to your endpoint, or forwards the UDP datagrams. Endpoints are Application or Network Load Balancers, EC2 instances or Elastic IP addresses, in one Region or several. A standard accelerator chooses among them by client location, health and the endpoint weights you set, and a traffic dial per endpoint group sends a percentage of its traffic elsewhere. When an endpoint fails its health checks, new connections go to the next healthy one at once. Nothing on the client changes, because the IPs never move; only the path behind them does.

So the questions are different. CloudFront asks "have I seen this response before?" Global Accelerator asks "which healthy Region is closest to this client?" A custom routing accelerator goes further and maps each client to a specific instance and port, which the documentation pitches at VoIP media servers and game sessions.

When to use which

  • Cacheable web content, images, video, downloads: CloudFront. Each hit is a request your origin never sees.
  • Dynamic HTTP APIs: usually CloudFront too, with caching off for those paths, for TLS at the edge, WAF and edge code; Global Accelerator fits when clients need fixed IPs.
  • Non-HTTP protocols, UDP, gaming, VoIP, MQTT over TCP: Global Accelerator. CloudFront only speaks HTTP.
  • Customers who allow-list IPs: Global Accelerator's two addresses are the default answer; CloudFront needs a requested Anycast static IP list.
  • Active-active or fast regional failover without waiting for DNS caches to expire: Global Accelerator.
  • Both at once is normal: CloudFront for the website, Global Accelerator for the game servers behind it.

Watch it run

The animation is CloudFront's half of the comparison, from the CloudFront and caching lesson. A viewer asks edge A for /app.js and misses, the regional edge cache misses too, and the S3 origin answers; both layers keep a copy. A second viewer's edge B misses but the regional cache hits, and a reload is served by edge A alone. Then a query string turns the same file into a new cache key, and a deploy leaves stale copies in every layer until they are cleared. Picture Global Accelerator on the same stage: no cache rows at all, and every arrow ends at a server in a Region.

CloudFront & Caching Layers

Step 1 of 10

The origin lives in one Region. Viewers are everywhere, so CloudFront puts caches in edge locations near them.

The same interactive animation as the lesson — step through it with the controls.

The code

A toy model, not either service. The accelerator part routes each edge to the lowest-latency healthy Region, and fails over when one Region goes down; the CDN part counts hits and origin fetches with a TTL:

# toy round-trip times (ms) from the edge a client lands on to each Region
LATENCY = {
    "frankfurt-edge": {"eu-west-1": 25, "us-east-1": 90, "ap-southeast-1": 160},
    "virginia-edge": {"eu-west-1": 80, "us-east-1": 8, "ap-southeast-1": 210},
    "tokyo-edge": {"eu-west-1": 220, "us-east-1": 150, "ap-southeast-1": 70},
}
STATIC_IPS = ("192.0.2.10", "198.51.100.10")    # the same two addresses, from every edge

def accelerate(edge, healthy):
    """Toy standard accelerator: the nearest healthy endpoint group wins."""
    options = [(ms, region) for region, ms in LATENCY[edge].items() if region in healthy]
    return min(options)[1] if options else None

def cdn(requests, ttl):
    """Toy CDN: each edge keeps a copy per cache key for ttl seconds."""
    cache, hits, origin_fetches = {}, 0, 0
    for t, edge, key in requests:
        if (edge, key) in cache and t - cache[(edge, key)] < ttl:
            hits += 1
        else:
            origin_fetches += 1
            cache[(edge, key)] = t
    return hits, origin_fetches

up = {"eu-west-1", "us-east-1", "ap-southeast-1"}
for edge in LATENCY:
    print(f"{edge:15}", STATIC_IPS[0], "->", accelerate(edge, up))
print("eu-west-1 fails:", "frankfurt-edge ->", accelerate("frankfurt-edge", up - {"eu-west-1"}))

edges = list(LATENCY)
static = [(t, edges[t % 3], f"/img/{t % 5}.png") for t in range(1000)]   # 15 distinct keys
api = [(t, edges[t % 3], f"/api/cart?user={t}") for t in range(1000)]   # every key unique
print("static, ttl 300:", cdn(static, ttl=300))
print("api,    ttl 300:", cdn(api, ttl=300))
# frankfurt-edge  192.0.2.10 -> eu-west-1
# virginia-edge   192.0.2.10 -> us-east-1
# tokyo-edge      192.0.2.10 -> ap-southeast-1
# eu-west-1 fails: frankfurt-edge -> us-east-1
# static, ttl 300: (940, 60)
# api,    ttl 300: (0, 1000)

The client in Frankfurt dials the same address before and after the failure; only the Region behind it changes. The CDN numbers show the other side: 1,000 static requests cost the origin 60 fetches, while an API whose every request has a unique key gets no benefit from caching at all, which is exactly the traffic Global Accelerator is built for. Both models checked against brute force on random inputs, a sorted scan for routing and a history scan for the cache:

import random

def accelerate_reference(edge, healthy):
    """Brute force: sort every Region by latency, take the first healthy one."""
    for ms, region in sorted((ms, r) for r, ms in LATENCY[edge].items()):
        if region in healthy:
            return region
    return None

def cdn_reference(requests, ttl):
    """Brute force: a request hits if an earlier fetch of that key is still fresh."""
    fetched, hits = [], 0
    for t, edge, key in requests:
        last = [ft for ft, fe, fk in fetched if (fe, fk) == (edge, key)]
        if last and t - last[-1] < ttl:
            hits += 1
        else:
            fetched.append((t, edge, key))
    return hits, len(fetched)

random.seed(7)
ok = True
regions = ["eu-west-1", "us-east-1", "ap-southeast-1"]
for _ in range(500):
    for edge in LATENCY:
        LATENCY[edge] = {r: random.randint(5, 250) for r in regions}
    healthy = {r for r in regions if random.random() < 0.6}
    ok &= all(accelerate(e, healthy) == accelerate_reference(e, healthy) for e in LATENCY)
    t, reqs = 0, []
    for _ in range(random.randint(1, 60)):
        t += random.randint(0, 40)
        reqs.append((t, random.choice(list(LATENCY)), f"/k{random.randint(0, 4)}"))
    ttl = random.choice([0, 30, 120])
    ok &= cdn(reqs, ttl) == cdn_reference(reqs, ttl)
print(ok)  # True

The complexity

The costs have different shapes:

  • CloudFront bills by usage: requests and data transferred out to viewers, varying by geography and price class, plus invalidation paths beyond a monthly free allowance. A high hit ratio also cuts what the origin serves and pays for.
  • Global Accelerator bills a fixed hourly fee per accelerator, enabled or disabled, plus a per-gigabyte premium on top of standard data transfer, charged in the dominant direction and varying by source Region and destination edge, plus public IPv4 address charges. Every byte still crosses to your endpoint.
  • Latency: CloudFront removes round trips; Global Accelerator shortens the ones it cannot remove, by terminating TCP near the client and moving traffic off the public internet early.

Where it goes wrong

  • Global Accelerator in front of static files. It pays a premium per gigabyte and the origin still serves every byte. Cacheable content belongs behind CloudFront.
  • Allow-listing CloudFront's current IPs. They change. Clients that need fixed addresses need an Anycast static IP list or Global Accelerator; origins that should accept only CloudFront can use the CloudFront origin-facing managed prefix list.
  • Expecting failover to move open connections. Global Accelerator keeps sending an established connection to its endpoint until the idle timeout, 340 seconds for TCP and 30 for UDP, even if the endpoint turns unhealthy; only new connections move.
  • Deleting an accelerator to save money. The static IPs go with it, and every customer firewall rule breaks. Disabling keeps them, and the hourly fee.
  • Testing with ping. Global Accelerator answers ICMP echo at the edge, so ping measures the edge, not your endpoint.

When it shows up in interviews

In global system design rounds, as "users in Asia complain about latency" or "how do you fail over between Regions?". The strong answer splits the traffic first: static and cacheable content through a CDN, dynamic or non-HTTP traffic through anycast routing to the nearest healthy Region. For the cache key and TTL details behind the CloudFront side, see CloudFront caching explained; for the load balancers that sit behind Global Accelerator as endpoints, see ALB vs NLB vs Gateway Load Balancer.

How to say it in an interview

"Both use AWS edge locations, but they do different jobs. CloudFront is an HTTP CDN: it terminates TLS at the edge, caches responses by a cache key, runs edge functions and WAF, and only goes to the origin on a miss; its IPs change, so clients use its domain name. Global Accelerator caches nothing: it gives me two static anycast IPs, takes TCP or UDP in at the nearest edge and carries it over the AWS backbone to the closest healthy endpoint in any Region, with health checks, weights and traffic dials. I use CloudFront for web content and Global Accelerator for non-HTTP traffic, fixed-IP requirements and fast regional failover."

Frequently asked questions

What is the difference between CloudFront and Global Accelerator?

CloudFront is a CDN for HTTP and HTTPS: it caches responses at edge locations and serves hits without contacting the origin. Global Accelerator caches nothing; it provides static anycast IP addresses and proxies TCP and UDP connections over the AWS global network to the nearest healthy regional endpoint.

Does Global Accelerator cache content?

No. Every connection is carried to an endpoint such as a load balancer or EC2 instance in a Region, which serves it. Global Accelerator improves the network path and availability, not the number of requests your servers handle. For caching, put CloudFront in front of the content.

Does CloudFront have static IP addresses?

Not by default: a distribution is reached through its domain name, and the edge IPs behind it change. You can request an Anycast static IP list through CloudFront support, intended for allow-listing and apex domains. Global Accelerator gives every accelerator two static IPv4 addresses without a request.

Sources