CDN Fundamentals - Global-Scale Content Delivery
LESSON
CDN Fundamentals - Global-Scale Content Delivery
By the end of this lesson, you will be able to...
Trace a catalog request through an edge cache, an origin fetch, and conditional revalidation.
Explain why a CDN needs both a safe sharing key and a freshness policy.
Diagnose whether poor edge performance comes from cacheability, key fragmentation, origin misses, or an unsafe sharing boundary.
Idea in one sentence: A CDN makes repeated content fast by serving a valid shared copy near the requester, but it can do that safely only when the key, freshness rule, and origin fallback describe the same response.
Core Insight
A customer in Madrid opens shop.example/products/42. The catalog service and database are in another region. The team puts a CDN in front of the site and expects the page to become fast everywhere.
At first, the model seems simple: a CDN is a cache that lives closer to the customer. That is true, but incomplete. A nearby cache helps only when it has a response that is both reusable for this request and still allowed to be served. An edge location with no matching object, an object that has expired, or a key that mixes two different users must involve the origin instead.
A CDN is therefore a request-path mechanism, not a bag of copies. It routes a request to an edge location, constructs or selects a cache key, decides whether the stored response is fresh, and either responds locally, revalidates, or fetches from origin. The speedup is earned by those decisions being correct.
The Situation: A Public Product Card and a Private Basket
Keep two requests in view:
GET /products/42?lang=es public product card
GET /basket signed-in customer's basket
The product card contains a title, image, and current display price. Many people can reuse the Spanish version. The basket contains one person's items and must never be shared with another person.
The origin service is authoritative for both. The CDN has edge points of presence, or PoPs, near groups of users. The names and timings below are a teaching model, not measurements from a particular provider.
Madrid customer
-> Madrid edge PoP
-> edge cache
-> origin catalog service, only when necessary
The public card can have a shared-cache policy such as a short freshness lifetime plus a validator. The basket needs a private or non-cacheable response policy. The URL alone is not enough to decide this: the response's sharing and freshness contract must say what may be reused.
The Initial Model: Every Edge Hit Is Good
If the Madrid edge holds the Spanish product card, returning it locally avoids a long request to the catalog origin. It also saves origin work: parsing the request, reading data, rendering a response, and sending bytes across the network. This is the happy path.
The naive extension is: “cache as much as possible and make the key as broad as possible.” A broad key raises the chance of a hit, but it can turn a hit into a data leak or a wrong response. If a cached page varies by language, currency, authorization, or tenant and the key omits that dimension, the edge can serve a valid copy of the wrong representation.
The opposite mistake is safer-looking but costly: include every header, cookie, and query parameter in the key. Then two requests that would receive the same public card map to different entries. The edge sees mostly misses; the origin sees nearly all traffic. A cache key is not an identity label for the request. It is a statement of which requests can safely share one response.
The Better Model: Three Decisions at the Edge
In plain English, the edge needs to answer three questions:
- What response is this request asking for? Build a key from the dimensions that change the representation.
- May this response be shared? Respect the privacy and authorization boundary.
- May the stored copy be used now? Apply its freshness lifetime or validate it with origin.
In this scenario, a reasonable public-card key might include the product id and selected language:
cache key = product:42 | language:es
It would not include an arbitrary session cookie merely because the browser sends one, if the response does not vary by that cookie. The basket cannot use that shared key; it needs Cache-Control: private, no-store, or another policy that keeps it out of shared storage according to its sensitivity. HTTP distinguishes private caches from shared caches, and a cookie alone does not make a response private. MDN's HTTP caching guide covers that boundary.
The technical terms for the third decision are freshness and revalidation. A fresh response can be reused under its policy. A stale response is not necessarily thrown away: the edge can ask the origin whether the known version is still valid, commonly with an ETag and If-None-Match. If it is unchanged, a small 304 Not Modified response lets the edge continue using its stored body. If it changed, the origin sends the new representation.
A Worked Trace: Miss, Hit, Then Revalidation
Assume the origin returns this public response at 10:00. The values are illustrative:
Cache-Control: public, max-age=60
ETag: "product-42-es-v18"
At first the Madrid edge has no matching entry.
| Time | Edge decision | Origin action | Result for the customer |
|---|---|---|---|
| 10:00:00 | Key is product:42|es; cache miss. |
Returns HTML and ETag v18. |
First request waits for origin; edge stores v18. |
| 10:00:08 | Same key; entry age is 8 seconds, so it is fresh. | None. | Edge returns stored v18 locally. |
| 10:01:10 | Same key; entry is stale. | Receives If-None-Match: "product-42-es-v18". |
If unchanged, origin returns 304; edge refreshes the stored entry's usability. |
| 10:01:10 | Same key; entry is stale. | Or returns new HTML with ETag: "product-42-es-v19". |
Edge stores v19 and returns the new card. |
The last two rows are alternatives. The edge does not guess which applies; the origin's validator decides. HTTP validation exists so a stale stored response can be checked without always transferring the full body. MDN documents conditional validation and 304 Not Modified.
Now change one request property. A French customer asks for GET /products/42?lang=fr. If Spanish and French genuinely differ, this must be a separate key. Returning Spanish would be a cache correctness failure; treating both languages as the same just to improve hit rate is not an optimization.
So far, the CDN has reduced repeated origin work for a reusable public response. It has not made the origin unnecessary, turned a private basket into safe shared data, or guaranteed instant delivery of an edit. Origin remains the source that defines the response and validates changes.
When the Origin Is Still on the Critical Path
A CDN hit is valuable, but many configurations accidentally turn every request into an origin request. Look for these paths:
edge has no entry -> origin fetch
edge key changes every request -> origin fetch
entry is stale and must validate -> origin validation
response is private / uncacheable -> origin fetch
origin is unhealthy -> edge may serve only what policy permits
This explains a common surprise: the CDN dashboard shows traffic, but users see little latency improvement. The useful signal is not “requests reached the CDN.” It is cache-status by request class: edge hit, miss, pass-through, revalidation, and error. Pair it with origin request rate and end-to-end p95/p99 latency. A high hit ratio for images can hide a low hit ratio for the HTML that dominates the user experience.
Origin shielding and multi-tier caching are possible provider features, but the mechanism here stays the same: one layer may reduce load on another only if it can safely reuse or validate a representation. Provider-specific routing and configuration depth belong in the HTTP and content-delivery track.
The Trade-off: Reuse Versus Correctness Surface
The CDN improves latency and origin capacity when many requests share a valid response. It costs policy work and creates more locations where a copy may exist.
- Broader sharing improves hit rate but risks mixing language, tenant, authorization, or device-specific responses.
- Narrower keys preserve correctness but split the cache and increase origin work.
- Longer freshness lowers validation traffic but permits older content for longer.
- Shorter freshness or forced validation tightens the origin relationship but raises origin request volume and can add latency after expiry.
- Explicit purge reduces a known stale object's lifetime but has its own scope, propagation, and refill consequences; the next lessons examine those mechanisms.
The best choice is situated. A versioned JavaScript asset can often be shared broadly and cached for a long time because a new URL names a new content version. A public product card may need a shorter lifetime and revalidation. A personalized checkout page should not enter a shared CDN cache merely because it is expensive to render.
The boundary appears when the cache policy hides a product requirement. A CDN cannot decide the correct price, undo a wrong cache key, or guarantee that a user sees a newly edited item everywhere at the same instant. Those are contracts that must include the origin, invalidation path, and sometimes the client experience.
Check: A CDN cache key uses only /products/42. The origin returns different product cards for Accept-Language: es and Accept-Language: fr. The hit rate rises after the change. Is that evidence of a successful optimization?
Think first, then reveal.
Answer: No. The key has merged two different representations. The higher hit rate may mean Spanish customers are receiving a French response or the reverse. Add language as a key dimension or use the corresponding HTTP variation semantics, then evaluate hit rate together with response correctness.
Practice: Review an Edge Policy Before Launch
The shop will run a global campaign. It has three endpoints:
| Endpoint | Requirement |
|---|---|
/assets/app.8f3.js |
Same bytes for everyone; a new deployment uses a new filename. |
/products/42?lang=es |
Public; may be up to 60 seconds old; language changes the text. |
/basket |
Signed-in and private; must show the customer's own current basket. |
For each endpoint, decide whether it belongs in a shared CDN cache, name the key or boundary, and state one signal you would inspect during the campaign.
A good answer should mention:
- long-lived shared caching for the versioned asset, with asset cache-hit ratio and origin asset requests as signals;
- a shared product-card key that includes the representation-changing language, a 60-second freshness rule or validator, and cache status plus stale-response reports as signals; and
- a private or non-shared basket policy, with authorization correctness and origin latency rather than shared hit rate as the relevant evidence.
Connections
The previous lesson established that invalidation is a freshness contract between an authority and its copies. A CDN applies that contract to shared copies near users, so an application-cache delete alone may not update the edge. The next lesson moves from this passive mechanism to edge functions: small decisions at the PoP can choose routing, cache keys, or response behavior, but they do not replace origin authority.
Resources
- [ARTICLE] HTTP caching — Focus: Inspect shared versus private storage, freshness,
Vary, validators, and conditional revalidation. - [DOCS] What is Amazon CloudFront? — Focus: Map the origin, distribution, and edge-location roles onto the request trace.
- [DOCS] Caching content with Fastly — Focus: Compare cache hits, misses, pass-through behavior, and provider-controlled edge policy.
Key Takeaways
- A CDN is a request-path mechanism: it routes, keys, checks freshness, and only then decides whether origin work is necessary.
- A shared-cache key must include every property that changes the representation and omit irrelevant request noise; hit rate without response correctness is not success.
- Freshness and conditional revalidation let an edge reuse a stored body while the origin remains the authority on whether it changed.
- Public versioned assets, public catalog cards, and private baskets need different sharing and freshness contracts.
- Inspect cache status by request class, origin request rate, correctness signals, and tail latency together; no single CDN metric proves the user path is healthy.
← Back to Caching, Workers, and Performance