Tiered Caching & Origin Shield
Tiered caching inserts a second, upstream cache layer between the CDN’s edge nodes and your origin so that a cold object costs one origin fetch instead of one fetch per point of presence, and this guide covers the topologies, wire behavior, offload math, and failure modes of that upper tier on Cloudflare, CloudFront, Fastly, and Akamai-style networks.
Key implementation points:
- A flat CDN gives every point of presence its own independent cache, so a single uncached object can generate as many concurrent origin requests as there are PoPs receiving traffic for it.
- An upper tier (Cloudflare’s Tiered Cache, CloudFront’s Origin Shield, a Fastly shield POP, an Akamai parent tier) becomes the only cache that talks to origin, and it coalesces the downstream misses into one fetch.
- Topology matters more than the on/off switch: a single designated shield close to the origin, a smart per-region upper tier, and a generic global tier produce very different miss latency and very different offload numbers.
- Shielding multiplies the effect of everything else in your cache config — a wasteful cache key or an aggressive purge is now wrong in two places instead of one, and the upper tier will happily amplify a bad decision.
Why a flat edge cache stampedes the origin
A CDN edge node is an autonomous cache. It has its own storage, its own eviction policy, and no knowledge of what any sibling node has already fetched. When a visitor in Frankfurt requests /assets/hero.webp and the Frankfurt PoP has never seen that object, it opens a connection to your origin and pulls the whole body. Ten minutes later a visitor in São Paulo asks for the same object, and the São Paulo PoP — which also has never seen it — repeats the entire transaction. Nothing about the first fetch helped the second.
For a handful of PoPs and a handful of objects this is invisible. It stops being invisible under three conditions that describe most real sites: a large catalog of objects, moderate per-object popularity, and a global audience. A product image that is requested a few dozen times a day worldwide will never be hot enough to stay resident everywhere, so every PoP that sees it fetches it, and the object’s origin request count is proportional to your geographic footprint rather than to its popularity.
The pathological version is the synchronized miss. Purge everything after a deploy, or let a popular object expire at the same instant in every region, and hundreds of edge nodes discover the miss within the same second. Your origin does not see one request — it sees a burst sized to your PoP count, arriving with no jitter. That is the thundering herd, and it is the single most common reason a CDN-fronted site still falls over during a release.
The arithmetic of independent misses
You can predict origin load without instrumentation. For a single object, the number of origin fetches over a measurement window is roughly:
origin_fetches(object) = PoPs_reached(object) x ceil(window / edge_ttl)
PoPs_reached is the count of edge nodes that saw at least one request for that object during a TTL period — not the size of the CDN. A globally popular object reaches most of the network; an object requested twenty times a day reaches maybe a dozen nodes. Summed across the catalog:
origin_fetches_total = SUM over objects of [ PoPs_reached x (window / edge_ttl) ]
Introduce a single upper tier and PoPs_reached collapses to 1 for every object, because the only cache that talks to origin is the tier itself:
origin_fetches_tiered = SUM over objects of [ 1 x (window / edge_ttl) ]
That is the whole idea. The edge-facing hit ratio barely moves — visitors were already being served from the edge most of the time — but the origin-facing request count drops by roughly the average fan-out factor. This is why offload and hit ratio are different numbers that people constantly conflate, a distinction worth getting right before you try to measure origin offload after enabling tiered caching.
Topology choices
Every provider ships some flavor of upper tier, but the topologies differ in ways that decide both your miss latency and your offload ratio.
Generic global tiering designates upper-tier PoPs by network position rather than by where your origin is. An edge node in Sydney is mapped to a nearby upper tier — usually one on the same continent — which then fetches from origin. Offload is good, added latency is modest, and there is nothing to configure beyond the on/off switch. The weakness is that with several upper tiers worldwide your origin still sees one fetch per tier, not one fetch globally.
Smart or regional tiering lets the provider choose the upper tier dynamically, usually the PoP that is closest to your origin on their private backbone, and to consolidate across regions. Cloudflare’s Smart Tiered Cache Topology is the canonical example: the network picks a single upper tier per zone based on measured latency to your origin, so the topology self-corrects if you move the origin. Regional Tiered Cache adds an intermediate regional layer between the edge and that upper tier, which helps when your traffic is spread across many continents and the single upper tier is far from most edges.
A single designated shield is the most explicit option: you name a region (CloudFront’s origin_shield_region) or a POP (Fastly’s backend shield), and every miss anywhere in the world is routed through it. Offload is maximal — one origin fetch per object per TTL, full stop — and the shield is a natural place to terminate origin mTLS or to whitelist a single set of source IPs. The trade-off is a hard dependency on one region’s availability and a latency penalty for edges far from it.
Request collapsing at the upper tier
Topology explains the steady state. Request collapsing — also called request coalescing — explains what happens in the first few hundred milliseconds of a miss, and it is the mechanism that actually kills the thundering herd.
When an upper tier receives a miss for an object and starts a fetch to origin, a second request for the same cache key arriving before the first fetch completes is not forwarded. It is parked on the in-flight fetch. When the origin response arrives, every parked request is served from the single response body. Fastly implements this as the default behavior for cacheable objects (you opt out per-request with req.hash_ignore_busy); Cloudflare and CloudFront do it implicitly at the tier; Varnish calls the parked state a “busy object.”
Collapsing and tiering solve adjacent problems and you want both. Tiering reduces the number of distinct caches that will ever ask origin for an object. Collapsing reduces the number of simultaneous asks from within one cache. Without collapsing, a single upper tier serving a 900 ms origin fetch for a hot object still forwards every request that arrives during those 900 ms. With collapsing, it forwards exactly one.
The cost of the extra hop
Nothing is free. A miss that used to travel edge → origin now travels edge → upper tier → origin, and the tier adds its own connection setup, cache lookup, and store. Whether that is a win depends on one comparison.
Let R_o be the round-trip time from the edge to your origin, R_t the round-trip from the edge to the upper tier, and H_t the hit ratio at the tier — the fraction of edge misses the tier can answer from its own storage. Expected added latency for an edge miss is:
before = R_o
after = R_t + (1 - H_t) x R_o_from_tier
When the tier is placed near the origin, R_o_from_tier is small (single-digit to low-double-digit milliseconds) and the tier absorbs most of the request. A concrete example: an edge in Singapore, an origin in eu-central-1, and a shield in Frankfurt. Direct edge-to-origin is roughly 170 ms. With the shield, the edge pays about 160 ms to reach Frankfurt over the CDN backbone plus 4 ms from Frankfurt to the origin — but only on the 20% of requests the shield itself misses. The expected cost lands near 163 ms instead of 170 ms, and the origin sees a fifth of the traffic.
The failure case is a badly placed tier. Put the shield in us-east-1 while your origin runs in Sydney and every miss makes a trans-Pacific detour: edge → Virginia → Sydney. You have added an entire ocean to the miss path in exchange for offload you probably did not need. The rule is blunt and reliable — the upper tier belongs next to the origin, not next to your users. Users are already served by the edge; the tier exists to be close to the thing it is protecting.
CDN backbones change this calculus in your favor. Cloudflare’s Argo Smart Routing, Fastly’s inter-POP paths, and CloudFront’s regional edge network carry tier-to-origin traffic over optimized paths with warm connections, so the second hop is usually cheaper than the equivalent public-internet path. That is why “an extra hop” rarely translates into “an extra full RTT” in practice.
Provider implementations
Cloudflare
Cloudflare exposes three related switches at the zone level. Tiered Cache turns on the upper tier; Smart Tiered Cache Topology lets Cloudflare pick a single upper tier based on measured latency to your origin; Regional Tiered Cache adds an intermediate regional layer for zones with globally distributed traffic. Argo Smart Routing is a separate paid feature that optimizes the path between tiers.
# Enable tiered caching on the zone
curl -X PATCH "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/argo/tiered_caching" \
-H "Authorization: Bearer $CF_API_TOKEN" \
-H "Content-Type: application/json" \
--data '{"value":"on"}'
# Choose the smart (latency-derived) topology
curl -X PATCH "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/cache/tiered_cache_smart_topology_enable" \
-H "Authorization: Bearer $CF_API_TOKEN" \
-H "Content-Type: application/json" \
--data '{"value":"on"}'
# Optional: add the regional layer for globally spread traffic
curl -X PATCH "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/cache/regional_tiered_cache" \
-H "Authorization: Bearer $CF_API_TOKEN" \
-H "Content-Type: application/json" \
--data '{"value":"on"}'
The same state in Terraform, which is where it belongs if you already keep DNS and CDN configuration as code:
resource "cloudflare_tiered_cache" "shop" {
zone_id = var.zone_id
cache_type = "smart" # "smart" | "generic" | "off"
}
resource "cloudflare_argo" "shop" {
zone_id = var.zone_id
tiered_caching = "on"
smart_routing = "on"
}
Cloudflare does not expose an upper-tier marker in the public response headers, which surprises people who expect a cf-tier field. The authoritative signal is the Logpush field CacheTieredFill, a boolean that is true when the edge filled from an upper tier rather than from origin. The step-by-step enablement and verification path is covered in enabling Tiered Cache and Origin Shield on Cloudflare.
AWS CloudFront
CloudFront already has a two-layer structure: viewer-facing edge locations and Regional Edge Caches. Origin Shield adds a third, explicitly pinned layer in a region you choose, and it is configured per origin rather than per distribution.
resource "aws_cloudfront_distribution" "app" {
enabled = true
origin {
domain_name = "origin.example.com"
origin_id = "app-origin"
# One shield region for every miss, worldwide.
origin_shield {
enabled = true
origin_shield_region = "eu-central-1" # put this where the origin lives
}
custom_origin_config {
http_port = 80
https_port = 443
origin_protocol_policy = "https-only"
origin_ssl_protocols = ["TLSv1.2"]
}
}
default_cache_behavior {
target_origin_id = "app-origin"
viewer_protocol_policy = "redirect-to-https"
allowed_methods = ["GET", "HEAD"]
cached_methods = ["GET", "HEAD"]
cache_policy_id = aws_cloudfront_cache_policy.static.id
compress = true
}
}
To flip it on an existing distribution without Terraform, patch the origin in the distribution config:
aws cloudfront get-distribution-config --id E1EXAMPLE123 > dist.json
# edit Origins.Items[0].OriginShield to {"Enabled": true, "OriginShieldRegion": "eu-central-1"}
aws cloudfront update-distribution \
--id E1EXAMPLE123 \
--if-match "$(jq -r .ETag dist.json)" \
--distribution-config "$(jq .DistributionConfig dist.json)"
CloudFront bills Origin Shield as an extra request charge on the shield layer, so it is not a pure win on cost — it trades request fees for origin egress and origin compute. On the wire, a response that traversed the shield returns an X-Amz-Cf-Id header containing multiple comma-separated identifiers, one per layer.
Fastly
Fastly attaches shielding to a backend, not to a service. You pick the POP code of the shield, and Fastly automatically routes edge misses through it. Request collapsing is on by default.
resource "fastly_service_vcl" "shop" {
name = "shop-production"
domain {
name = "www.example.com"
}
backend {
name = "origin_eu"
address = "origin.example.com"
port = 443
use_ssl = true
# Shield POP code — pick the POP nearest the origin.
shield = "frankfurt-de"
connect_timeout = 2000
first_byte_timeout = 15000
between_bytes_timeout = 10000
}
force_destroy = true
}
VCL runs on both tiers, and req.backend.is_shield lets you branch on which one you are executing in. That matters because you usually want origin-side logic (surrogate key tagging, auth header injection) to run only on the shield:
sub vcl_recv {
# Normalizing on both tiers keeps the two cache keys identical.
set req.url = querystring.regfilter(req.url, "^(utm_|fbclid|gclid)");
if (req.backend.is_shield) {
# Only the shield talks to the real origin; add origin auth here.
set req.http.X-Origin-Auth = "shared-secret-value";
}
return(lookup);
}
sub vcl_fetch {
# Let the shield hold objects longer than the edge does.
if (req.backend.is_shield) {
set beresp.ttl = 3600s;
}
set beresp.stale_while_revalidate = 600s;
set beresp.stale_if_error = 86400s;
return(deliver);
}
Akamai-style parent and child tiers
Akamai’s Tiered Distribution follows the same parent/child model: edge (child) servers are mapped to a parent tier, and only the parent contacts origin. It is a property behavior rather than a zone switch, and the parent tier is selected by map code.
{
"name": "tieredDistribution",
"options": {
"enabled": true,
"tieredDistributionMap": "CH2"
}
}
Combine it with cacheKeyQueryParams so the parent and child tiers derive identical keys, and with prefetch behaviors if you want the parent to warm objects ahead of demand. Akamai exposes the parent-tier result in debug headers (X-Cache-Remote) alongside the edge result (X-Cache), which makes it one of the easier platforms to verify from the client side.
Platform comparison
| Provider | Mechanism | Wire behavior | Failover support |
|---|---|---|---|
| Cloudflare | Tiered Cache with generic, smart, or regional topology; Argo optimizes the tier path | No public tier header; cf-cache-status reports the edge result only, CacheTieredFill in Logpush reports the fill source |
Automatic — if the upper tier is unreachable the edge falls back to a direct origin fetch |
| AWS CloudFront | Origin Shield, configured per origin with a fixed OriginShieldRegion |
X-Cache: Hit from cloudfront; X-Amz-Cf-Id carries one id per traversed layer |
Shield outage falls back to Regional Edge Cache then origin; region is static, no automatic relocation |
| Fastly | Shield POP set on the backend; request collapsing on by default | X-Cache: MISS, HIT and X-Served-By list both POPs, edge last; X-Cache-Hits gives per-tier counts |
Edge bypasses an unhealthy shield and goes direct to origin; health checks run per backend |
| Akamai | Tiered Distribution parent/child with a map code | X-Cache for the edge and X-Cache-Remote for the parent tier under the debug pragma |
Parent selection is map-driven and re-homes automatically on parent failure |
Configuration procedure
-
Establish the baseline first. Record origin requests per minute, origin bytes out, and CDN cache hit ratio over a full weekly cycle. Without this you cannot prove the change did anything, and “it feels faster” is not a rollback criterion.
-
Fix the cache key before you shield. An upper tier only collapses requests that share a key. If your key still contains tracking parameters or a high-cardinality
Vary, the tier will store thousands of near-identical objects and offload almost nothing. Work through cache key and Vary configuration first — this is the step people skip and then blame the shield. -
Choose the tier location. Measure RTT from candidate shield regions to the origin and pick the lowest. On CloudFront that is a literal region name; on Fastly a POP code; on Cloudflare, prefer the smart topology and let the network measure for you.
# Rough proxy for shield-to-origin latency from a host in the candidate region for i in 1 2 3 4 5; do curl -s -o /dev/null -w '%{time_connect} %{time_starttransfer}\n' \ https://origin.example.com/healthz done -
Enable the tier on a single hostname or behavior first. On CloudFront, shield one origin. On Fastly, shield one backend. On Cloudflare the switch is zone-wide, so stage it on a non-production zone that points at the same origin.
-
Verify the request actually traverses the tier. Request the same object from several geographically separate vantage points and read the cache status headers (next section). A cold object requested from a second region should be a HIT if the tier already holds it.
-
Watch origin concurrency, not just origin request count. The most valuable signal is the drop in peak simultaneous origin connections, because that is what protects you during a purge or a deploy.
-
Re-measure after a full traffic cycle — a weekday and a weekend at minimum — then decide to keep, retune, or revert.
Reading the wire: cache status headers
Each provider reports tier traversal differently, and knowing exactly which header to grep saves hours.
# Cloudflare: edge status only. Repeat from two regions; the second should be HIT
# if the upper tier already holds the object.
curl -sI https://www.example.com/assets/hero.webp \
| grep -iE 'cf-cache-status|age|cf-ray'
# cf-cache-status: HIT
# age: 412
# cf-ray: 8f2a1b3c4d5e6f70-SIN
# CloudFront: two ids in X-Amz-Cf-Id means the request crossed a shield/regional layer.
curl -sI https://d111111abcdef8.cloudfront.net/assets/hero.webp \
| grep -iE 'x-cache|x-amz-cf-pop|x-amz-cf-id|age'
# x-cache: Hit from cloudfront
# x-amz-cf-pop: SIN52-P1
# x-amz-cf-id: kQ2h...==,7Bd1...==
# Fastly: two POPs in X-Served-By, shield first, edge last.
curl -sI https://www.example.com/assets/hero.webp \
| grep -iE 'x-cache|x-served-by|x-cache-hits|age'
# x-cache: HIT, HIT
# x-served-by: cache-fra-eddf8230065-FRA, cache-sin-wsss1830032-SIN
# x-cache-hits: 4, 19
# Akamai: enable the debug pragma, then read edge and parent separately.
curl -sI -H 'Pragma: akamai-x-cache-on, akamai-x-cache-remote-on' \
https://www.example.com/assets/hero.webp | grep -iE 'x-cache'
# X-Cache: TCP_MEM_HIT from a23-45-67-89
# X-Cache-Remote: TCP_HIT from a98-76-54-32
The interpretation that matters: X-Cache: MISS, HIT on Fastly means the shield missed and the edge hit, reading right to left as the response travels back. MISS, MISS means the object came from origin. If you never see two entries in X-Served-By, shielding is not active on that backend.
Calculating origin offload
Offload is the fraction of edge-visible requests that your origin never sees:
offload_ratio = 1 - (origin_requests / edge_requests)
Work an example. A catalog site serves 60,000,000 edge requests per day across 12,000 distinct cacheable objects with a one-hour edge TTL. Traffic is global, and telemetry shows each object is requested from an average of 18 PoPs per hour.
| Layer | Formula | Requests/day | Offload |
|---|---|---|---|
| Edge requests | measured | 60,000,000 | — |
| Flat cache: origin fetches | 12,000 x 18 x 24 | 5,184,000 | 91.4% |
| Single upper tier: origin fetches | 12,000 x 1 x 24 | 288,000 | 99.5% |
| Reduction in origin work | 5,184,000 - 288,000 | 4,896,000 fewer | 94.4% fewer fetches |
The headline offload only moved from 91.4% to 99.5%, which sounds unimpressive until you look at the absolute number: origin request volume fell by a factor of eighteen. This is exactly why offload ratio is a misleading headline metric near the top of its range, and why you should also report origin requests per second and peak origin concurrency.
Two adjustments make the estimate honest. First, the tier does not have infinite storage, so its own hit ratio is below 100% and a fraction of tier misses still reach origin — multiply the tiered figure by 1 / H_t. Second, purges reset the whole calculation for the affected objects, so measure over a window without a full purge in it.
Interaction with purge, cache keys, and stale serving
Purge. Adding a tier adds a cache that must also be invalidated. Every major provider purges all tiers as part of a single purge operation — a Cloudflare purge, a CloudFront invalidation, or a Fastly surrogate-key purge reaches the upper tier as well as the edges. The operational difference is in the shape of the recovery. After a flat purge, every PoP independently refills from origin. After a tiered purge, every PoP refills from the tier, which refills once from origin. Tiering therefore turns “purge everything” from a dangerous operation into a merely expensive one, and it pairs particularly well with cache tags for surrogate-key purging because the tag purge is applied at the tier too.
Cache keys. The upper tier computes the same cache key as the edge unless you deliberately rewrite the request between tiers. That is a hard constraint: any request attribute that varies per PoP — a geolocation header, a client IP, a CF-IPCountry value — will fragment the tier’s storage exactly as badly as it fragments the edge’s. If you normalize the key in an edge function, make sure the normalization runs before the tier fetch, not after. On Fastly, this is why the querystring.regfilter call in the example above sits in vcl_recv without an is_shield guard.
Stale-while-revalidate. Tiering and stale serving are complementary and should be deployed together. When the tier holds an object with stale-while-revalidate, every downstream edge that asks for it during the revalidation window is served the stale copy instantly while a single background fetch refreshes the tier. Without the tier, each edge runs its own background revalidation and origin sees the herd anyway, just asynchronously. Configure the directives as described in stale-while-revalidate and resilient caching, and lengthen the tier’s TTL relative to the edge’s so the tier is the layer with the authoritative fresh copy.
Origin TTLs. A tier makes long origin-facing TTLs safer, because you can now purge with confidence rather than waiting for expiry. If you have been keeping edge TTLs short as an implicit safety net, revisit that decision alongside your Cache-Control and CDN TTL policy once the tier is live.
Troubleshooting and rollback
| Symptom | Likely cause | Diagnosis | Fix |
|---|---|---|---|
| No measurable change in origin load | Cache key varies per request, so nothing collapses | Compare distinct cache keys per object in edge logs | Normalize query strings and headers, then re-measure |
| Origin load unchanged for HTML only | HTML is not cacheable at all, so tiering never applies | cf-cache-status: DYNAMIC or X-Cache: Miss on every request |
Make the response cacheable first; a tier cannot cache what the edge refuses to |
| MISS latency doubled | Shield placed far from the origin | Compare time_starttransfer on a MISS before and after |
Move the shield region; prefer smart topology |
| Origin load spikes at a fixed hour | Synchronized TTL expiry that the tier reproduces | Plot origin requests per minute against TTL boundaries | Add jitter to TTLs, or enable stale-while-revalidate at the tier |
| Purge no longer takes effect quickly | A tier holding a copy the purge did not reach | Age stays high after purge on the affected object |
Confirm the purge API covers all tiers; purge by tag rather than by URL |
| Origin sees requests from unexpected IPs | Traffic now originates from the tier, not the edge | Inspect source addresses in origin access logs | Update origin allow-lists to the provider’s full published ranges |
Rollback protocol. Tiering is one of the safest CDN changes to reverse because it is a routing decision, not a content change.
- Turn the tier off at the same scope you enabled it — zone setting, distribution origin, or backend attribute. No purge is required.
- Expect a short spike in origin requests as edges resume fetching directly for objects that were only resident at the tier.
- Confirm the rollback on the wire: Fastly’s
X-Served-Byreturns to a single POP, CloudFront’sX-Amz-Cf-Idto a single id. - Keep the cache-key normalization you did in step 2 of the procedure. It is beneficial with or without a tier, and reverting it is the mistake that turns a clean rollback into a hit-ratio regression.
Edge cases and gotchas
- Range requests fragment badly at the tier. Video and large-file delivery generates overlapping byte-range requests. Unless the provider does range coalescing (Fastly’s segmented caching, CloudFront’s automatic range handling), the tier stores range fragments and origin sees more requests than you expect.
- Edge compute can bypass the tier entirely. A subrequest issued from a Worker or edge function with default settings may go straight to origin rather than through the upper tier. Route such fetches through the cache API, or accept that your function traffic is unshielded.
- Origin allow-lists break silently. If your origin firewall only accepts the CDN’s edge ranges, and the tier fetches from a different address block, you get 403s that look like an application bug. Always allow the provider’s complete published range set.
- mTLS and client certificates now terminate at the tier. The upper tier presents the origin certificate, not the edge. Certificate pinning at origin against a specific edge identity will fail after enablement.
- A tier can mask an origin that is already broken. Higher offload means fewer origin health signals. Keep synthetic origin health checks running independently of user traffic, the same discipline used for edge health checks and automatic failover.
- Vary explosion is worse with a tier, not better. A
Vary: User-Agentthat produced a poor edge hit ratio produces an equally poor tier hit ratio, and you now pay for storage twice. - Uncacheable responses gain nothing and cost a hop. A
Set-Cookieon an API response makes it uncacheable at every layer, so shielding adds latency with zero offload. Exclude those paths from the shield where the provider allows it. - Cost is not always lower. CloudFront charges for shield-layer requests, and Cloudflare’s smart topology sits behind a paid entitlement. Model the request fees against the origin egress and compute you are saving before assuming a net win.
Frequently Asked Questions
Does an origin shield increase latency for my users? Only on a cache miss, and usually by less than the raw extra hop suggests. Cache hits at the edge never touch the tier at all, and a well-placed tier answers most misses itself, so the additional origin round-trip applies to a small slice of traffic. If MISS latency doubles after enablement, the shield is in the wrong region relative to your origin.
Do I still need tiered caching if my cache hit ratio is already 98%? Usually yes, because hit ratio and origin offload measure different things. A 98% edge hit ratio still leaves 2% of a large request volume hitting origin, and in a flat CDN those misses are multiplied by the number of PoPs that independently need to fill. Tiering attacks the multiplier, not the ratio.
Does purging still work correctly with an upper tier? Yes. Cloudflare, CloudFront, Fastly, and Akamai all propagate a purge to every tier, so a single purge call invalidates the edge and the parent. The behavior that changes is refill: after the purge, edges refill from the tier and the tier makes one origin fetch, which is precisely why tiering makes aggressive purging survivable.
Should the upper tier be close to my users or close to my origin? Close to the origin. The edge layer already handles proximity to users; the tier’s job is to shorten and consolidate the origin path. Pinning the shield near your largest audience is the most common misconfiguration and it produces good offload numbers with poor miss latency.