Build a CDN (13 scenes)
Scene 04 · TTL — origin tells the edge how long to trust the copy
max-age applies to every cache, including the browser; s-maxage overrides it for shared caches like the CDN — and TTL is what flips a cell from fresh to stale.
Previously
The user is now reaching a nearby POP — but how long does that POP hold the cached copy before checking origin again? The origin tells it via Cache-Control, and the dial that lets the CDN hold for a day while the browser holds for a minute is s-maxage.
Scene 04
TTL — origin tells the edge how long to trust the copy
Diagram
Top: an origin response headers panel showing the live Cache-Control directives. Below it, two parallel timeline lanes — BROWSER (uses max-age) and EDGE (uses s-maxage) — each with a cached cell that is green when fresh and gray when stale, plus a countdown bar ticking down to 0. Bottom: an origin RPS strip that stays at 0 while the edge cell is fresh and ticks up the moment it goes stale. **TTL** — time-to-live; how long a cached copy is considered fresh before it needs revalidation. **Cache-Control** — origin response header that sets cache lifetime; `max-age` applies to every cache including the browser; `s-maxage` overrides max-age for shared caches like the CDN.
A response just arrived at the POP with `Cache-Control: public, max-age=60, s-maxage=3600`. The EDGE cell shows 1:00:00 ticking, the BROWSER cell shows 1:00 ticking — both green. Watch the clock advance: the browser will turn gray well before the edge does.
Implementation
Cache.parseCacheControl(header, role)
shared caches override max-age with s-maxage; browsers ignore it
1def parseCacheControl(header, role):2 d = parseDirectives(header) # k=v pairs3 if 'no-store' in d:4 return Lifetime(ttl=0, store=False)5 max_age = int(d.get('max-age', 0))6 s_maxage = d.get('s-maxage') # may be absent7 if role == 'shared' and s_maxage is not None:8 return Lifetime(ttl=int(s_maxage))9 return Lifetime(ttl=max_age)
Cache.isFresh(cell, now)
the TTL countdown — fresh until age exceeds the lifetime
1def isFresh(cell, now):2 if cell.lifetime.ttl == 0:3 return False # born stale (e.g. max-age=0)4 age = now - cell.created_at5 return age < cell.lifetime.ttl
Cache.serve(request, role)
lookup, freshness check, hit-or-revalidate
1def serve(request, role):2 cell = store.lookup(request.url)3 if cell is None:4 return forwardToOrigin(request) # MISS5 if isFresh(cell, now()):6 return cell.response # HIT7 # stale: must revalidate before serving8 return revalidate(cell, request)