Revalidation — the cheap question with the expensive wait
When a cached copy goes stale, the edge could ask the origin a yes/no question before re-downloading the whole body — that question is called a conditional GET, and the origin's tiny 'no, it hasn't changed' answer is called 304 Not Modified. Bytes are saved; the round trip is not.
When the edge's copy goes stale, it does not re-download the whole body — it asks origin a cheap question first.
Scene 05
Revalidation — the cheap question with the expensive wait
- Watch
- Try it
- Predict
- Capture
The cell starts FRESH. After a moment its TTL expires and the next request triggers a conditional GET — the edge asks origin 'is this still v7?'. Origin returns a thin 304 (no body), the edge serves the stored bytes locally, and the cell goes back to FRESH.
Highlighted lines are the ones running in the diagram right now.
def handleRequest(url):cell = cache.lookup(url)if cell.cacheControl == 'no-store':return origin.fetch(url) # always full 200if cell.cacheControl == 'no-cache':return revalidate(cell) # ask every time# max-age: serve locally while freshif cell.fresh:return cell.body # ~2 ms, no RTTreturn revalidate(cell) # stale -> ask
def revalidate(cell):headers = {}if cell.etag: # If-None-Match: "v7"headers['If-None-Match'] = cell.etagresp = origin.fetch(cell.url, headers) # full RTTif resp.status == 304:cell.refreshTTL() # body unchangedreturn cell.body# 200 OK: origin sent a new body + new ETagcell.body = resp.bodycell.etag = resp.headers['ETag']return cell.body
def handleGET(url, headers):asset = store.load(url)clientEtag = headers.get('If-None-Match')if clientEtag and clientEtag == asset.etag:# short-circuit: empty body, ETag in headersreturn Response(status = 304,headers = { 'ETag': asset.etag },body = None,)return Response(200, asset.headers, asset.body)
Where this sits in Build a CDN
Scene 05 of 13, in the Freshness act — TTL, revalidation, stale-while-revalidate.. When stale, the edge sends a conditional GET with the ETag; origin replies 304 Not Modified — body is empty, but the round trip isn't.
Up next. The user still waits one origin RTT on every revalidation — unless we let the edge serve stale immediately and refresh in the background.