CDN Explained: How It Works, Setup & Cache Invalidation
Learn how a CDN works, how to enable one, which cache headers matter, and every way to invalidate or purge a CDN cache, with diagrams and interview answers.

A CDN (Content Delivery Network) keeps copies of your content on servers close to your users, so pages load faster and your own servers do far less work.
To use one: point your domain at it, send correct Cache-Control headers, and lock your origin down. To keep content fresh: prefer versioned file names and short TTLs, use tag or URL purges for targeted changes, and treat purge everything as a last resort.
This guide follows the story in order: the problem, the life of one request, what gets cached, how long, how to turn it on, how to keep it fresh, how to secure and scale it, and how to talk about it in a senior-level interview.
How to Read This Guide
Each part builds on the one before it. If you are short on time, read the TL;DR above and the cheat sheet in Part 11. If you are preparing for an interview, read everything, then jump to Part 10.
Part 1 — The Problem: Why Distance Hurts, and What a CDN Is
1.1 An intuition first
Imagine one giant warehouse in Virginia that holds every product your company sells. Every customer in the world orders from it. A customer in Bengaluru waits days; the warehouse is overwhelmed on sale day; and if it burns down, nobody gets anything.
Now imagine the same company opens hundreds of small local stores. Each store keeps the popular items in stock. Most orders are filled from the store down the road. Only rare items, or items the store has not stocked yet, are fetched from the warehouse.
That is a CDN.
CDN = a worldwide chain of local stores (edges) that stock copies of your popular content, backed by one central warehouse (your origin).
Everything else in this guide is about three questions: what should the stores stock, how long before it goes stale, and how do I tell them when something changed.
1.2 The vocabulary
1.3 What a CDN actually fixes
Our running example is a Twitter-like app. A single page load pulls an avatar, a JavaScript bundle, CSS, tweet images and a timeline API response.
A CDN trades a little freshness for a lot of speed, scale and resilience. Every decision later in this guide is about controlling that trade.
Part 2 — The Life of a Request
Let us follow one request, in order, from the moment a user types a URL.
flowchart LR
A[1. DNS lookup] --> B[2. Route to nearest edge]
B --> C[3. TCP + TLS to the edge]
C --> D[4. Cache lookup]
D -->|hit| E[5a. Serve from edge]
D -->|miss| F[5b. Fetch from origin, store, serve]
style A fill:#6B7280,stroke:#4B5563,color:#fff
style B fill:#8B5CF6,stroke:#6D28D9,color:#fff
style C fill:#8B5CF6,stroke:#6D28D9,color:#fff
style D fill:#06B6D4,stroke:#0E7490,color:#fff
style E fill:#22C55E,stroke:#15803D,color:#fff
style F fill:#3B82F6,stroke:#2563EB,color:#fffThe flowchart above is the whole story in five boxes. The rest of this part zooms into each one.
2.1 Step 1: DNS decides, not the URL
A common beginner question is: how does a URL know whether to hit the CDN or the origin?
It does not. DNS decides which server receives the request. When you enable a CDN, you change what your hostname resolves to:
Before: www.example.com → A 203.0.113.10 (your origin server)
After: www.example.com → CNAME d123.cloudfront.net (the CDN)
→ resolves to a nearby edge IP
From that moment, every browser asking for www.example.com receives the CDN's address, so requests reach the CDN automatically. With Cloudflare's proxied mode (the orange cloud), the public DNS answer is Cloudflare's edge IP, and your real origin IP is never exposed.
The CDN then looks up your hostname in its own configuration to learn where your origin is:
Host: www.example.com → CDN config → origin = origin.example.com (or an S3 bucket)
The browser never sees the origin address. Only the CDN does.
2.2 Step 2: Finding the nearest healthy edge
Your CDN has hundreds of edges worldwide, but your users all type the same hostname. Something has to answer one question for each user: which edge should this person talk to?
There are two ways to answer it. A phone-line analogy makes the difference easy to remember.
DNS-based routing is calling a company's main office, where a receptionist says: 'For you, please call the Chennai branch on this number.' Different callers get different numbers.
Anycast is a company with one national phone number. The phone network itself connects each caller to the nearest branch. Everyone dials the same number.
Short version: DNS decides which IP address you use. Anycast makes one IP address lead to the nearest machine.
Method A: DNS-based routing (GeoDNS, latency-based)
Every user gets a different IP address, chosen for them at the moment they look up the hostname.
sequenceDiagram
autonumber
actor U as User (Bengaluru)
participant R as User's DNS Resolver
participant A as CDN Authoritative DNS
participant M as CDN Mapping System
U->>R: Where is www.example.com?
R->>A: Query (+ optional client subnet hint)
A->>M: Which PoP is best for this location?
Note over M: Inputs: network location, measured latency,<br/>PoP health, PoP load, cost, customer rules
M-->>A: Chennai PoP (203.0.113.7)
A-->>R: 203.0.113.7 (TTL 30s)
R-->>U: 203.0.113.7
Note over U: Different users get different IPsThe CDN runs its own authoritative DNS server and a mapping system behind it. The mapping system continuously measures latency between networks and PoPs, and tracks which PoPs are healthy and how busy they are. The DNS answer is the result of that calculation.
Method B: Anycast
Every user gets the same IP address. Many PoPs around the world announce that address to the internet using BGP, the protocol networks use to tell each other which IP ranges they can reach.
flowchart TB
U1[User in Bengaluru] --> I1[ISP router]
U2[User in Frankfurt] --> I2[ISP router]
U3[User in Dallas] --> I3[ISP router]
I1 -->|shortest BGP path| P1[PoP Chennai<br/>announces 198.51.100.10]
I2 -->|shortest BGP path| P2[PoP Frankfurt<br/>announces 198.51.100.10]
I3 -->|shortest BGP path| P3[PoP Dallas<br/>announces 198.51.100.10]
style U1 fill:#6B7280,stroke:#4B5563,color:#fff
style U2 fill:#6B7280,stroke:#4B5563,color:#fff
style U3 fill:#6B7280,stroke:#4B5563,color:#fff
style I1 fill:#3B82F6,stroke:#2563EB,color:#fff
style I2 fill:#3B82F6,stroke:#2563EB,color:#fff
style I3 fill:#3B82F6,stroke:#2563EB,color:#fff
style P1 fill:#8B5CF6,stroke:#6D28D9,color:#fff
style P2 fill:#8B5CF6,stroke:#6D28D9,color:#fff
style P3 fill:#8B5CF6,stroke:#6D28D9,color:#fffThe diagram shows three users sending packets to the same IP. Each one's own ISP forwards the packets along the best BGP path it knows, which usually ends at the nearest PoP. Nobody made a per-user decision. The internet's routing did it.
Failover is the party trick. If a PoP fails, it stops announcing the address (or its BGP session drops). Within seconds to a minute, routers around the world learn that path is gone, and traffic flows to the next-nearest PoP. No DNS answers need to expire.
Side by side
In practice: most CDNs combine them
The two are not rivals. They solve different layers of the problem, and real providers mix them:
- DNS returns anycast addresses. Even when DNS does the first step, the IPs it returns may be anycast, so each region still has fast failover underneath.
- DNS picks a region or cluster, anycast picks the machine. Coarse steering from DNS, with routing and load balancing inside the PoP doing the rest.
- Different products, different mixes. Cloudflare and Fastly lean heavily on anycast. Akamai and CloudFront have historically relied heavily on DNS-based mapping, and also offer anycast options in places. Architectures change, so check each provider's current documentation.
You rarely configure any of this. You just point a CNAME at the CDN. But it affects three practical things:
- Failover design. DNS-based steering means DNS TTLs matter. Anycast means failover is faster but not instant.
- Debugging. To see which PoP served you, read the response headers: CloudFront shows
x-amz-cf-pop(for example a code starting withBLR), and Cloudflare'scf-rayends with the data center code. - Interviews. You are expected to explain both mechanisms, plus their trade-offs.
'DNS-based routing computes a nearest-PoP IP per user using measured latency, health and load, which gives fine control but is limited by DNS caching. Anycast announces one IP from many PoPs and lets BGP deliver users to a nearby one, which fails over fast but gives coarser control. Most CDNs combine both.'
2.3 Steps 3 to 5: connect, look up, answer
Once the browser has the edge's IP, it connects (TCP and TLS, over a short distance), then asks for the object. The edge looks it up in its cache.
sequenceDiagram
autonumber
actor U as User (Bengaluru)
participant R as Recursive DNS Resolver
participant A as CDN Authoritative DNS
participant E as Edge PoP (Chennai)
participant O as Origin (us-east-1)
U->>R: Resolve www.example.com
R->>A: Query (CNAME to d123.cdn-provider.net)
A->>A: Pick best PoP (geo, latency, health, load)
A-->>R: A record = Chennai PoP IP (short TTL)
R-->>U: Chennai PoP IP
U->>E: TCP + TLS handshake (short round trip)
U->>E: GET /static/app.9f3c1a.js
alt Cache hit
E-->>U: 200 from edge memory or disk
else Cache miss
E->>O: GET (over a warm, reused connection)
O-->>E: 200 + Cache-Control: max-age=31536000
E->>E: Store object
E-->>U: 200
endThe diagram shows DNS steering a user in Bengaluru to a Chennai PoP, followed by either a hit or a miss.
2.4 Hit vs miss, side by side
The first request for an object is a miss: the edge fetches it, stores it, and answers. Every later request is a hit: the origin is never involved.
sequenceDiagram
autonumber
actor U1 as User A (Mumbai)
actor U2 as User B (Mumbai)
participant E as Edge PoP (Mumbai)
participant O as Origin (us-east-1)
Note over U1,O: First request: cache MISS
U1->>E: GET /img/avatar_42.jpg
E->>E: Lookup cache key, not found
E->>O: GET /img/avatar_42.jpg
O-->>E: 200 + Cache-Control: max-age=86400
E->>E: Store object (TTL 24h)
E-->>U1: 200 (X-Cache: Miss, Age: 0)
Note over U1,O: Second request: cache HIT
U2->>E: GET /img/avatar_42.jpg
E->>E: Lookup, found, fresh
E-->>U2: 200 (X-Cache: Hit, Age: 312)User B never touches the origin. The cost of the miss is paid once per object per edge, or even less with a shield.
2.5 Two common setups
Two details trip people up:
- The origin needs its own name. If the origin were also called
www.example.com, the CDN would loop back to itself. Use something likeorigin.example.com, or an IP address, with the originalHostheader forwarded. - Someone can skip the CDN if they learn your origin's address. That bypasses your cache, WAF and rate limits. Part 5.5 shows how to lock the origin down.
Even for uncacheable requests (an API call marked no-store), a CDN helps. The slow TCP and TLS handshakes happen over a short hop to the edge, and the edge reuses long-lived, pre-warmed connections to the origin. This is called dynamic site acceleration.
The URL never chooses. DNS sends users to the CDN, and the CDN then chooses hit, miss or pass-through based on its cache key and rules. That is the subject of the next part.
Part 3 — Deciding What Gets Cached
Before the edge can say 'I have this', it has to know what 'this' means.
3.1 The cache key
The cache key is the CDN's definition of 'the same object'. By default it is roughly scheme + host + path + query string. Two requests with the same key share one cached copy, and two requests with different keys do not.
You control the key with a cache policy. Choosing it well is the single biggest factor in your hit ratio.
A response that differs per user (a logged-in page) but is cached under a shared key will be served to other users. That is a data leak, not a performance bug. When in doubt, use Cache-Control: private or no-store, and never let the CDN cache a response that carries Set-Cookie.
3.2 What to cache and what never to
Classify your content first. Each class gets its own strategy.
Decide what counts as the same object (the key) and which content is safe to share (the classification). Next you decide how long each class may be reused.
Part 4 — Controlling Freshness with Cache-Control
The origin tells every cache what to do, using HTTP response headers. Learning these is the single most valuable CDN skill.
4.1 The directives that matter
Think of them in three groups: how long, who may store it, and what to do when it expires or fails.
These directives are defined in RFC 9111 (HTTP Caching) and RFC 5861 (stale-while-revalidate and stale-if-error). MDN's Cache-Control reference is a handy companion.
4.2 Defaults for our system
# Hashed static assets
Cache-Control: public, max-age=31536000, immutable
# App shell (index.html)
Cache-Control: no-cache
# Public API (edge 30s, browser 0, serve stale while refreshing)
Cache-Control: public, max-age=0, s-maxage=30, stale-while-revalidate=60, stale-if-error=300
# Personalised response
Cache-Control: private, no-store
4.3 Revalidation: cheap refreshes with ETag
When an object expires, the edge does not have to download it again. It asks 'has this changed?' using a validator such as an ETag. If the origin answers 304 Not Modified, only headers travel, and the edge resets the freshness timer.
sequenceDiagram
autonumber
actor U as User
participant E as Edge
participant O as Origin
U->>E: GET /api/trending
Note over E: Cached copy is stale (TTL expired), ETag "v42"
E->>O: GET /api/trending (If-None-Match: "v42")
alt Unchanged
O-->>E: 304 Not Modified (no body, tiny)
E->>E: Reset freshness timer
else Changed
O-->>E: 200 + new body + ETag "v43"
E->>E: Replace cached object
end
E-->>U: 200 (fresh content)4.4 stale-while-revalidate: nobody waits
With stale-while-revalidate, an expired object is served instantly while the edge refreshes it in the background.
sequenceDiagram
autonumber
actor U as User
participant E as Edge
participant O as Origin
Note over E: s-maxage=30, stale-while-revalidate=60
U->>E: GET /api/trending at t=45s (expired, inside SWR window)
E-->>U: 200 stale copy, instantly
E->>O: Background revalidate (async)
O-->>E: 200 new content
E->>E: Update cache
U->>E: GET /api/trending at t=50s
E-->>U: 200 fresh copyThe origin is the boss. It sets the rules in headers, and the CDN follows them. A good default is: hashed assets for a year, HTML revalidated, public APIs for seconds with stale-while-revalidate, private data never shared.
Part 5 — Turning It On: How to Enable a CDN
You now know how a request flows, what gets cached, and how long. Time to switch it on.
5.1 Pull or push
5.2 The enablement checklist
Follow these in order. Each step protects the next.
5.3 Example A: AWS CloudFront in front of S3
resource "aws_cloudfront_origin_access_control" "oac" {
name = "tweets-media-oac"
origin_access_control_origin_type = "s3"
signing_behavior = "always"
signing_protocol = "sigv4"
}
resource "aws_cloudfront_distribution" "media" {
enabled = true
aliases = ["media.example.com"]
http_version = "http2and3"
price_class = "PriceClass_All"
origin {
domain_name = aws_s3_bucket.media.bucket_regional_domain_name
origin_id = "s3-media"
origin_access_control_id = aws_cloudfront_origin_access_control.oac.id
}
default_cache_behavior {
target_origin_id = "s3-media"
viewer_protocol_policy = "redirect-to-https"
allowed_methods = ["GET", "HEAD", "OPTIONS"]
cached_methods = ["GET", "HEAD"]
compress = true
# Managed policy: CachingOptimized
cache_policy_id = "658327ea-f89d-4fab-a63d-7e88639e58f6"
}
viewer_certificate {
acm_certificate_arn = aws_acm_certificate.media.arn # must be in us-east-1
ssl_support_method = "sni-only"
}
restrictions { geo_restriction { restriction_type = "none" } }
}
The bucket policy then allows s3:GetObject only to the CloudFront service principal for this distribution. This is Origin Access Control (OAC), so the bucket is never public.
5.4 Example B: Cloudflare (proxy mode)
- Add the site, and change your registrar's nameservers to Cloudflare's.
- In DNS, set the record for
www(or the apex) to Proxied (the orange cloud). Traffic now flows through the edge. - Cloudflare caches common static file types by default, but not HTML or JSON. Use Cache Rules to cache the paths you choose, set Edge TTL, and respect or override origin headers.
- Enable Tiered Cache, Brotli, HTTP/3 and 'Always Use HTTPS'.
5.5 Locking down the origin
5.6 Verify it works
curl -sI https://static.example.com/static/app.9f3c1a.js
HTTP/2 200
cache-control: public, max-age=31536000, immutable
content-encoding: br
age: 4821 # seconds the object has lived at the edge
x-cache: Hit from cloudfront # CloudFront; Cloudflare uses cf-cache-status: HIT
via: 1.1 abc.cloudfront.net (CloudFront)
Enabling a CDN is mostly DNS plus headers plus lockdown. Test with curl -I, and roll out one path class at a time.
Part 6 — Keeping Content Fresh: Cache Invalidation
Everything is cached and fast. Then you ship a fix, or delete a tweet, and the edges still serve the old version. This is the hard part.
'There are only two hard things in Computer Science: cache invalidation and naming things.'
It is hard because you are updating copies on hundreds of servers you do not control, while more copies sit in users' browsers.
6.1 Mental model: there are three layers of cache
flowchart LR
B[Browser cache] --> E[Edge cache]
E --> S[Shield cache]
S --> O[(Origin)]
style B fill:#6B7280,stroke:#4B5563,color:#fff
style E fill:#8B5CF6,stroke:#6D28D9,color:#fff
style S fill:#06B6D4,stroke:#0E7490,color:#fff
style O fill:#3B82F6,stroke:#2563EB,color:#fffA purge only clears the edge and shield layers. It does not reach the browser cache. If you served a file with max-age=1 year, every browser that has it keeps it, and you cannot recall it.
Design so that browsers never hold content you might need to change. Hashed file names for assets, and no-cache (revalidate) for HTML.
6.2 The ladder of preference
Invalidation is a fallback, not a strategy. The best invalidation is none. Try these in order.
6.3 The full menu of techniques
6.4 Commands: invalidating all of it
# --- AWS CloudFront ---
# '/*' counts as ONE invalidation path. The first 1,000 paths per month are free,
# after that you are charged per path.
aws cloudfront create-invalidation \
--distribution-id E123ABC456DEF \
--paths "/*"
aws cloudfront create-invalidation --distribution-id E123ABC456DEF \
--paths "/static/*" "/index.html"
# --- Cloudflare ---
curl -X POST "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/purge_cache" \
-H "Authorization: Bearer $CF_TOKEN" -H "Content-Type: application/json" \
--data '{"purge_everything": true}'
# by URL / by tag / by prefix:
# {"files": ["https://example.com/a.css"]}
# {"tags": ["tweet-101"]}
# {"prefixes": ["example.com/static/"]}
# --- Fastly ---
curl -X POST "https://api.fastly.com/service/$SERVICE_ID/purge_all" \
-H "Fastly-Key: $FASTLY_TOKEN"
# purge by surrogate key (soft purge: add header Fastly-Soft-Purge: 1)
curl -X POST "https://api.fastly.com/service/$SERVICE_ID/purge/tweet-101" \
-H "Fastly-Key: $FASTLY_TOKEN"
Rate limits, per-path charges, propagation time and available purge types change by provider and plan. In an interview, state the pattern and say you would check current limits. In production, read the docs.
6.5 Pattern 1: the clean deploy (zero purge for assets)
Upload new hashed files first, upload the HTML last, and let old and new versions coexist.
sequenceDiagram
autonumber
participant CI as CI/CD
participant S3 as Origin Bucket
participant CDN as CDN
actor U as Users
CI->>CI: Build, filenames hashed (app.9f3c1a.js)
CI->>S3: Upload new hashed assets FIRST
Note over S3: Old and new assets coexist
CI->>S3: Upload index.html LAST (Cache-Control: no-cache)
CI->>CDN: Purge only /index.html (or nothing, if revalidating)
U->>CDN: GET /index.html
CDN-->>U: New HTML referencing app.9f3c1a.js
U->>CDN: GET /static/app.9f3c1a.js
CDN-->>U: Miss, then cached for 1 year
Note over U,CDN: Users on the old page still fetch the old hashed file successfullyUploading assets before the HTML, and keeping old assets around for a while, prevents 404s for users who are mid-session on the previous version.
6.6 Pattern 2: tag-based purge for dynamic content
The origin labels each response with surrogate keys. When a tweet is deleted, an event-driven worker purges that tag after the database commit, so the next read misses and gets a fresh 404.
sequenceDiagram
autonumber
actor Author as Alice
participant API as Tweet Service
participant DB as Database
participant Q as Event Bus
participant P as Purge Worker
participant CDN as CDN
actor Reader as Bob
Reader->>CDN: GET /api/tweets/101
CDN->>API: Miss
API-->>CDN: 200 + Surrogate-Key: tweet-101 user-42 + s-maxage=300
CDN-->>Reader: 200 (cached for 5 min)
Author->>API: DELETE /tweets/101
API->>DB: BEGIN, delete, COMMIT
API->>Q: Publish TweetDeleted(101)
Q->>P: Consume event
P->>CDN: Purge tag tweet-101 (soft or hard)
CDN-->>P: Accepted
Reader->>CDN: GET /api/tweets/101
CDN->>API: Miss (purged)
API-->>CDN: 404
CDN-->>Reader: 404Note the order: commit to the database first, then purge. Purging before the commit lets the edge re-cache the old data. Driving purges from an event (or a transactional outbox) also makes them retryable if the CDN API call fails.
6.7 What happens when you purge everything
A purge is an API call to the CDN control plane, which fans the command out to every PoP. Propagation typically takes from under a second to a few minutes, depending on the provider.
The danger is what comes next: every edge is suddenly empty, and traffic that was being absorbed by caches now falls on your origin all at once. This is the thundering herd, or cache stampede.
sequenceDiagram
autonumber
actor Admin as Deploy pipeline
participant CP as CDN Control Plane
participant E1 as Edge PoP 1
participant E2 as Edge PoP N
participant Sh as Origin Shield
participant O as Origin
actor Users
Admin->>CP: POST purge (/* or tag=tweet-101)
CP-->>Admin: 201 accepted (async)
par Fan out
CP->>E1: Invalidate matching keys
and
CP->>E2: Invalidate matching keys
end
Note over E1,E2: Cache now empty (or marked stale)
Users->>E1: 100,000 req/s for hot object
Users->>E2: 100,000 req/s for hot object
E1->>Sh: Miss (collapsed into 1 request)
E2->>Sh: Miss (collapsed into 1 request)
Sh->>O: 1 request (collapsed)
O-->>Sh: 200
Sh-->>E1: 200 (cached)
Sh-->>E2: 200 (cached)
E1-->>Users: Served
E2-->>Users: ServedThe diagram shows how an origin shield with request collapsing turns a storm of misses into a single origin request.
Version the URL if you can, shorten the TTL if you cannot, tag-purge if you must, purge-all only in an emergency. And remember that purges never reach browsers.
Part 7 — Securing the CDN
Caching adds a new risk: shared storage of responses. These are the failure modes a senior engineer checks.
Most CDN security incidents are one of two mistakes: a private response cached under a shared key, or an origin reachable without the CDN. Fix those two first.
Part 8 — Making It Fast, Cheap and Measurable
8.1 Origin shield and tiered caching
Without a shield, 200 PoPs can each miss on the same object, producing 200 origin requests. With a shield (a designated mid-tier cache near the origin), edges ask the shield first, and the shield collapses their misses into a single origin request.
flowchart LR
U[Users worldwide] --> E1[Edge PoP A]
U --> E2[Edge PoP B]
U --> E3[Edge PoP C]
E1 -->|miss| S[(Regional Shield Cache)]
E2 -->|miss| S
E3 -->|miss| S
S -->|miss, collapsed| O[(Origin)]
style U fill:#6B7280,stroke:#4B5563,color:#fff
style E1 fill:#8B5CF6,stroke:#6D28D9,color:#fff
style E2 fill:#8B5CF6,stroke:#6D28D9,color:#fff
style E3 fill:#8B5CF6,stroke:#6D28D9,color:#fff
style S fill:#06B6D4,stroke:#0E7490,color:#fff
style O fill:#3B82F6,stroke:#2563EB,color:#fff8.2 The levers
8.3 Observability: what to watch
Once the basics work, the biggest wins come from hit ratio (clean cache keys), shielding (protect the origin), and measuring (so regressions are caught the day they ship).
Part 9 — The Full Picture: One Page Load in Our Twitter-Like App
Every concept so far, in a single flow. Bob in Bengaluru opens the app.
The browser resolves DNS to the nearest edge, revalidates the HTML, gets static assets and trending data from cache, fetches an image through the shield on a miss, and sends the personalised timeline straight to the origin without caching it.
sequenceDiagram
autonumber
actor U as Bob (Bengaluru)
participant DNS as DNS / Anycast
participant E as Edge PoP
participant Sh as Shield
participant API as App / API
participant S3 as Media Store
participant DB as DB + Read Replica
U->>DNS: Resolve www.example.com
DNS-->>U: Nearest edge
U->>E: GET / (index.html, no-cache)
E->>API: Revalidate (If-None-Match)
API-->>E: 304
E-->>U: HTML (references app.9f3c1a.js)
par Static and media
U->>E: GET /static/app.9f3c1a.js
E-->>U: 200 (immutable, 1y)
and
U->>E: GET /media/img_8841.avif
E->>Sh: Miss
Sh->>S3: Origin fetch (OAC)
S3-->>Sh: 200
Sh-->>E: 200 (cached)
E-->>U: 200
and
U->>E: GET /api/trending (s-maxage=30, SWR=60)
E-->>U: 200 from edge cache
end
U->>E: GET /api/home (private, no-store, with auth)
E->>API: Pass through (warm connection)
API->>DB: Read from replica
DB-->>API: Timeline rows
API-->>E: 200 (Cache-Control: private)
E-->>U: 200 (not stored at the edge)Part 10 — The Interview Playbook (Senior Architect Perspective)
10.1 A seven-step framework for any 'add a CDN' question
Walk through these in order, out loud. It shows structured thinking, and it covers everything an interviewer might probe.