Dinesh/ Blog
systems

CDN — Edge, Cache Hierarchies, Cache-Control

Cache keys are isolation boundaries. A source-bounded lesson with worked reasoning, failure analysis and explicit runtime limitations.

20 min readChecking device speech…
Lesson preparation & details

Level: intermediate

By the end, you should be able to

  • Derive edge and shield offload from measured populations
  • Set storage, freshness, validation and variant policies per response class
  • Test private bypass and targeted purge without claiming browser revocation

Bring with you

Sources checked: . A source check does not change the publication or update date.

Editorial review: · What review means

In this article · 32 sections

Why this session exists

A CDN moves some connection handling and reusable responses closer to callers. It can reduce origin work and latency, but no universal tenfold p95 improvement, 95% hit rate or 90% bill reduction follows from enabling it. The dangerous mistake is not a low hit rate: it is reusing a private response for the wrong caller. Learn hierarchy, freshness, validation, cache keys and purge as one correctness contract.

Prerequisites

Know HTTP status/headers (S015), reverse proxies (S062) and cache-aside/TTL/invalidation (S063). The local exercise uses an in-memory edge and synthetic origin. Varnish and provider configuration remain source-reviewed reference material; no server, container, CDN account, paid resource, purge API or real security probe is used.

Intuition: regional bookstores and the central catalogue

Imagine regional bookstores stocking popular titles while a central catalogue remains authoritative. A local copy can avoid a long trip; a cold item still requires one. The example is about locality, not a literal claim that one library owns every book or that one percent of every workload accounts for ninety percent of demand.

The origin produces the authoritative representation, an edge is near some clients, and an optional shield aggregates misses before they reach the origin. Routing may use DNS, anycast and provider policy; “nearest” can mean a chosen network path rather than geographic distance. Each tier has independent storage, eviction, validation and failure behavior.

Benefits and limits beyond static files

Caching can remove an origin round trip and computation. Edge TLS termination and reused upstream connections can reduce repeated setup cost for uncacheable traffic. Routing/security features can also help, but introduce another trusted processing layer. A CDN cannot remove propagation time for dynamic origin work, guarantee DDoS immunity, or make every API faster. Measure from representative regions, with controlled protocol/reuse/cache state and equal responses.

Evolution from object delivery to reverse-proxy/security services and programmable edge platforms explains today's feature mix. RFC 9111/8246 define caching/immutable semantics; TLS 1.3 and QUIC change setup behavior. Product support, cache defaults, pricing and feature availability are release/account contracts, not historical inevitabilities or “no cold starts” guarantees.

Edge, shield and origin hierarchy

Edge, shield and origin hierarchy
Figure text equivalent — labels and relationships
  • Node “Client” (square).
  • Node “Edge cache” (square).
  • Node “Optional shield” (square).
  • Node “Origin” (square).
  • “Client” leads to “Edge cache”. Line: normal; ends: arrow point.
  • “Edge cache” leads to “Optional shield”: Miss or validation. Line: normal; ends: arrow point.
  • “Optional shield” leads to “Origin”: Miss or validation. Line: normal; ends: arrow point.
  • “Edge cache” leads to “Client”: Usable hit. Line: normal; ends: arrow point.

A shield can share a fetched object across edges and coalesce concurrent identical misses if supported and configured. It is not guaranteed to collapse 200 arbitrary edge requests into exactly one origin request: keys, variants, authorization, race windows, locations and cacheability matter. It can also add latency to a miss and become another capacity/dependency boundary. Enable it from workload evidence, not “always.”

Work the 90/9/1 example instead of treating it as a rule

Suppose 1000 requests produce 900 edge hits. Of the remaining 100, the shield serves 90 and sends 10 to origin. The overall shares are 90%, 9%, 1%, while the conditional shield hit ratio is 90/100 = 90%. If response latencies in this synthetic mixture are 20, 60 and 150 ms, its mean is 0.9*20 + 0.09*60 + 0.01*150 = 24.9 ms. The p95 is 60 ms under this discrete example, not the mean and not a universal tenfold gain. Byte offload can differ from request offload when object sizes differ.

HTTP caching: storage, freshness and validation

A cache first decides whether a response may be stored, then whether it can be reused for this request, then whether validation is needed. Status/method, Authorization rules, Cache-Control and key/variant matching all matter. No single header alone decides every case.

  • max-age=N: freshness lifetime for caches under the applicable rules, not only browsers.
  • s-maxage=N: overrides max-age/Expires for shared caches, not just CDNs. RFC 9111 also gives it proxy-revalidation semantics; do not combine directives mechanically without reading interactions.
  • private: an unqualified response directive prevents shared-cache storage; it can permit private browser caching. It is not encryption.
  • no-store: do not store the request/response as specified, in volatile or nonvolatile storage; it does not remotely erase all previously retained copies or make malicious software comply.
  • no-cache: storage is allowed, but reuse requires successful validation under the directive's rules. It does not mean “zero cache storage.”
  • must-revalidate: once stale, do not reuse without successful validation under the standard's restrictions. It is not a directive to contact origin on every fresh hit.
  • public: explicitly allows shared caching in cases where it might otherwise be restricted. Do not stamp it on every authenticated response.
  • immutable: declares that the representation will not change during its freshness lifetime. Use genuinely content-versioned bytes and publish the new URL in a refreshed manifest/HTML; a timestamp-changing /app.js is not immutable.

Validators and Age

An ETag identifies a representation version under its strong/weak semantics; Last-Modified is a date validator with limitations. A GET with matching If-None-Match can receive 304, preserving the stored body while updating relevant metadata. If-None-Match supports lists, weak comparison for GET/HEAD and *; exact string equality alone is an incomplete implementation. If-None-Match takes precedence over If-Modified-Since when both are present. A 304 has no response content; its wire size is not a universal 43 bytes.

Age estimates the time since origin generation or validation as calculated through caches. It is not simply “seconds in this PoP.” Inspect Date, Age, Cache-Control, validators and the provider's cache status. A response can be stale but allowed under a specific stale policy; an old Age is not alone proof of a bug.

TTL and stale serving have separate bounds

Freshness is an age comparison, not a promise that the origin has not changed: a response is fresh while its calculated current age is less than its freshness lifetime. For a response with max-age=600, stale-while-revalidate=30, RFC 5861 permits up to 30 additional seconds of stale reuse during asynchronous revalidation, subject to applicable restrictions. At age 630 the extra window is exhausted; a quiet cache does not get to restart that allowance when its next request arrives. If there is no request during the window, background validation need not happen.

stale-if-error=1200 on a 600-second-fresh response can permit reuse after a qualifying error up to age 1800, not indefinitely and not 1200 seconds after each new failure. Neither extension grants storage permission to a private response. RFC 9111 forbids stale generation when an applicable directive such as must-revalidate, proxy-revalidate or shared-cache s-maxage prohibits it. Do not add stale options blindly to the earlier catalogue policy; decide which contract you actually need and verify the provider's supported behavior.

Worked decision. A news summary might tolerate a short stale window; checkout stock or authorization revocation cannot be treated as a day-old informational view. Purge removes selected shared copies, but neither purge nor a TTL repairs an authorization-key collision or revokes a browser copy. Bound maximum age separately at every tier and monitor validation failures.

# CPU-only policy arithmetic, not an HTTP cache or vendor simulator.
def permitted_age(age, fresh_for, swr=0, sie=0, error=False,
                  stale_forbidden=False):
    if min(age, fresh_for, swr, sie) < 0:
        raise ValueError("ages and durations must be nonnegative")
    if age < fresh_for:
        return "fresh"
    if stale_forbidden:
        return "validate-or-fail"
    allowance = sie if error else swr
    if allowance > 0 and age < fresh_for + allowance:
        return "stale-if-error" if error else "stale-while-revalidate"
    return "validate-or-fail"
 
assert permitted_age(599, 600, 30) == "fresh"
assert permitted_age(600, 600, 30) == "stale-while-revalidate"
assert permitted_age(630, 600, 30) == "validate-or-fail"
assert permitted_age(1799, 600, sie=1200, error=True) == "stale-if-error"
assert permitted_age(1800, 600, sie=1200, error=True) == "validate-or-fail"
assert permitted_age(601, 600, 30, stale_forbidden=True) == "validate-or-fail"

The model uses a conservative exclusive end boundary. It omits HTTP age calculation, request directives, storage eligibility, error classification and actual asynchronous work. The earlier Edge model implements neither stale extension nor real authentication; its boolean bypass tests cache isolation policy only.

Cache keys are isolation boundaries

A key normally starts with method/target URI under implementation rules, then representation variants. Vary names request fields used for response selection. A conforming cache must match their values under the field's rules before reuse; Vary: * prevents normal reuse without validation. Product configuration may add or override key behavior and some CDNs do not honor every Vary field automatically. Verify the exact platform rather than assuming standards support from a header.

For a public catalogue, language and negotiated encoding can change bytes. A key omitting language can serve French to an English request; one omitting a meaningful query can serve the wrong page. Conversely a timestamp or per-user identifier in every public asset key can destroy reuse. Normalize only dimensions proven irrelevant to the representation and authorization decision—never strip signed/security parameters merely for hit rate.

Set-Cookie is not a universal no-cache command. RFC 9111 explicitly says it does not inhibit caching by itself. Cloudflare's captured default behavior documents product-specific handling; configured cache rules can differ. Put explicit private/no-store on personalized responses and conservatively bypass authenticated traffic in a design that does not intentionally support secure shared personalization. Vary: Authorization alone is not a complete authorization or privacy design.

Per-content policies

Content classExample policyWhy and caveat
Content-hashed public JS/CSSpublic, max-age=31536000, immutableSame URL must keep the same bytes; preserve old assets during rollout/rollback.
Mutable public HTMLno-cache plus ETag, or a measured short freshness lifetimeHTML discovers new asset URLs; validation can return 304.
Public catalogue viewpublic, max-age=30, s-maxage=300 plus real variantsThese values are policy choices; here shared freshness is 300 seconds.
Account/admin responseprivate, no-store and shared-cache bypassAvoid cross-user reuse; also protect logs, browser history and access checks.

The table's public catalogue is informational, not the authoritative inventory decision at checkout. Correctness-sensitive writes revalidate against the source.

Hands-on: deterministic origin, variants, validation and purge

This deliberately small HTTP-cache model handles one GET route family and simple ETag lists. It is not a complete RFC implementation. The origin's static asset really has stable bytes, HTML changes only when its version changes, and authenticated requests bypass the shared cache. A logical clock makes freshness boundaries testable without sleeping.

import hashlib
from dataclasses import dataclass
 
ASSET = b'console.log("stable");\n'
ASSET_PATH = '/static/app.' + hashlib.sha256(ASSET).hexdigest()[:12] + '.js'
 
def etag(body):
    return '"' + hashlib.sha256(body).hexdigest() + '"'
 
def matches(header, current):
    if header.strip() == '*':
        return True
    # Restricted fixture tags contain no commas; not a general HTTP field parser.
    return any(tag.strip().removeprefix('W/') == current.removeprefix('W/')
               for tag in header.split(','))
 
@dataclass
class Stored:
    body: bytes
    tag: str
    expires: int
    tags: set
 
class Origin:
    def __init__(self):
        self.version = 1
        self.calls = 0
        self.not_modified = 0
 
    def get(self, path, language, validator=''):
        self.calls += 1
        if path == ASSET_PATH:
            body, ttl, tags = ASSET, 31536000, {'assets'}
        else:
            body = f'{path}|{language}|version={self.version}'.encode()
            ttl, tags = 30, {'catalogue'}
        tag = etag(body)
        if validator and matches(validator, tag):
            self.not_modified += 1
            return 304, b'', tag, ttl, tags
        return 200, body, tag, ttl, tags
 
class Edge:
    def __init__(self, origin):
        self.origin = origin
        self.now = 0
        self.entries = {}
 
    def get(self, path, language='en', authenticated=False):
        if authenticated:
            status, body, tag, ttl, tags = self.origin.get(path, language)
            return 'BYPASS', body
        key = (path, language)
        old = self.entries.get(key)
        if old and self.now < old.expires:
            return 'HIT', old.body
        status, body, tag, ttl, tags = self.origin.get(
            path, language, old.tag if old else '')
        if status == 304:
            assert old is not None
            body = old.body
        self.entries[key] = Stored(body, tag, self.now + ttl, tags)
        return ('REVALIDATED' if status == 304 else 'MISS'), body
 
    def purge_path(self, path):
        for key in list(self.entries):
            if key[0] == path:
                del self.entries[key]
 
    def purge_tag(self, tag):
        for key, entry in list(self.entries.items()):
            if tag in entry.tags:
                del self.entries[key]
 
o = Origin(); e = Edge(o)
assert e.get(ASSET_PATH)[0] == 'MISS'
assert e.get(ASSET_PATH) == ('HIT', ASSET)
en = e.get('/catalogue', 'en')[1]
fr = e.get('/catalogue', 'fr')[1]
assert en != fr
calls = o.calls
e.now = 30
assert e.get('/catalogue', 'en') == ('REVALIDATED', en)
assert o.calls == calls + 1 and o.not_modified == 1
o.version = 2
e.purge_path('/catalogue')
assert all(k[0] != '/catalogue' for k in e.entries)
assert e.get(ASSET_PATH)[0] == 'HIT'
assert e.get('/catalogue', 'en')[1] != en
before = dict(e.entries)
assert e.get('/account', authenticated=True)[0] == 'BYPASS'
assert e.entries == before
e.purge_tag('catalogue')
assert all('catalogue' not in x.tags for x in e.entries.values())
assert matches('W/' + etag(ASSET), etag(ASSET))
assert matches('"other", ' + etag(ASSET), etag(ASSET))
assert abs((.9*20 + .09*60 + .01*150) - 24.9) < 1e-12
print('immutable bytes, Vary model, 304, bypass and targeted purge: PASS')

Anatomy and negative controls

The key contains language; removing it in a negative control makes two distinct representations collide. Purging one path removes all its language variants but leaves the asset; tag purge removes every fixture catalogue entry. An authenticated request must neither read nor populate a shared entry. The model tests 304 body reuse, exact expiry and changed-origin refill rather than inferring caching from a timestamp that may not change within one second.

For encoding variants, an actual origin must implement content negotiation, generate the encoding and declare its policy. Some proxies normalize/recompress gzip automatically, so deleting Vary does not guarantee the same visible corruption on every product. A deterministic language-key collision demonstrates the isolation principle without pretending to have reproduced a vendor bug.

Varnish reference: a conservative local edge

The a72 original bound its origin to all interfaces, changed “immutable” bytes on every request, and exposed an unauthenticated PURGE handler. Binding that origin to loopback alone would not make it reachable through a container's host-gateway address. The replacement uses a native same-host topology. Keep the pure Origin logic above for unit tests; a real HTTP adapter must also emit Content-Length, Cache-Control, ETag and any Vary fields, handle conditional GET correctly and bind 127.0.0.1:9000.

Append this adapter to the model file for the reference origin. It implements the four route classes, stable ETags, explicit length, language variants and no-store account data. Its account payload is a synthetic fixture, not real authentication. Only the model runs in this review; this adapter is syntax/source reviewed.

# HTTP origin adapter — reference only; no listener started in this review.
from http.server import BaseHTTPRequestHandler, ThreadingHTTPServer
from urllib.parse import urlsplit
 
class OriginHandler(BaseHTTPRequestHandler):
    protocol_version = 'HTTP/1.1'
 
    def do_GET(self):
        path = urlsplit(self.path).path
        if path not in (ASSET_PATH, '/', '/index.html', '/api/catalogue', '/api/me'):
            self.send_response(404)
            self.send_header('Content-Length', '0')
            self.send_header('Cache-Control', 'no-store')
            self.end_headers()
            return
        language = 'fr' if self.headers.get('Accept-Language', '').startswith('fr') else 'en'
        private = path == '/api/me'
        validator = '' if private else self.headers.get('If-None-Match', '')
        status, body, tag, ttl, tags = self.server.origin.get(path, language, validator)
        if path == ASSET_PATH:
            policy = 'public, max-age=31536000, immutable'
            ctype = 'application/javascript'
        elif path == '/api/catalogue':
            policy = 'public, max-age=30, s-maxage=300'
            ctype = 'text/plain; charset=utf-8'
        elif private:
            policy = 'private, no-store'
            ctype = 'text/plain; charset=utf-8'
        else:
            policy = 'public, max-age=30, must-revalidate'
            ctype = 'text/plain; charset=utf-8'
        self.send_response(status)
        self.send_header('Cache-Control', policy)
        self.send_header('ETag', tag)
        self.send_header('Vary', 'Accept-Language')
        if status != 304:
            self.send_header('Content-Type', ctype)
            self.send_header('Content-Length', str(len(body)))
        self.end_headers()
        if status != 304:
            self.wfile.write(body)
 
    def log_message(self, *args):
        pass
 
def serve_origin_reference():
    with ThreadingHTTPServer(('127.0.0.1', 9000), OriginHandler) as server:
        server.origin = Origin()
        server.serve_forever()

The HTML-shell route is deliberately plain text in this minimal adapter; it teaches freshness/validators rather than browser markup. The public API is also explicitly text/plain rather than falsely labelled JSON. A real application substitutes correctly typed representations. Static content does not depend on language, so omitting Vary on that route would improve reuse; the conservative reference retains it without claiming optimal hit rate.

This VCL 4.1 reference targets Varnish 7.5 documentation and its tagged built-in VCL. It is intentionally conservative: private/no-store/no-cache/Set-Cookie responses pass instead of claiming the model's 304 policy is automatically Varnish's behavior. A local PURGE ACL is suitable only for the isolated exercise—behind a reverse proxy, trusting the proxy's source IP alone can expose purge to its callers.

vcl 4.1;
backend default { .host = "127.0.0.1"; .port = "9000"; }
acl purge_clients { "127.0.0.1"; }
 
sub vcl_recv {
    if (req.method == "PURGE") {
        if (client.ip !~ purge_clients) { return (synth(403)); }
        return (purge);
    }
    if (req.method != "GET" && req.method != "HEAD") { return (pass); }
    if (req.http.Authorization || req.http.Cookie) { return (pass); }
}
 
sub vcl_backend_response {
    if (beresp.http.Set-Cookie ||
        beresp.http.Cache-Control ~ "(?i)(private|no-store|no-cache)") {
        set beresp.uncacheable = true;
        set beresp.ttl = 0s;
        return (deliver);
    }
    # The built-in behavior still applies after this custom subroutine.
}
 
sub vcl_deliver {
    if (obj.hits > 0) { set resp.http.X-Cache = "HIT"; }
    else { set resp.http.X-Cache = "MISS-OR-PASS"; }
}

The broad directive check is a conservative teaching filter, not a complete Cache-Control parser. The built-in VCL's safety behavior matters even when custom rules are short. Do not claim a missing custom no-store block automatically makes default Varnish cache private data. MISS-OR-PASS intentionally avoids claiming every non-hit is a fill.

A separately authorized local integration would first compile the VCL with the installed Varnish release, then run the native origin and Varnish listener on explicit loopback ports in a disposable prefix. Keep exact process IDs and cleanup in finally; never broad-kill origin.py or remove a preexisting named container. Check first miss/next hit on the real hashed URL, bypass on an account route, language variants, and a targeted local purge. A validation test must inspect actual origin requests and response metadata; do not assert a 304 after 60 seconds when the origin body changes every second. This review runs none of these services.

Configuring a provider and proving purge scope

For a Cloudflare-style setup, first establish DNS/proxy routing and valid TLS on both client-edge and edge-origin hops. Define eligibility by content class; bypass personalized paths and authentication/session inputs unless a reviewed design explicitly supports them. Set origin headers, then inspect cache-rule overrides, query dimensions and supported Vary behavior. The captured Cloudflare defaults do not imply that every JSON API is cached by default.

Use a targeted URL purge for a known object and its configured variants, or tags/prefix/host options supported by the actual product/account. Cache-tag and surrogate-key header names differ by vendor. Authenticate the control operation through the supported service flow and record its accepted scope; no credential-bearing example or live purge is part of this lesson.

After a purge, probe the relevant edges/shields under an authorized plan and inspect validators/body identity. Cloudflare Workers Cache API is data-center-local according to its documentation; cache.delete is not a global purge and its Cache API does not automatically implement tiered caching. A global provider purge still cannot erase an already stored browser or search-engine copy. Separate revocation/access enforcement from content refresh.

Physical distance and timing measurements

Propagation distance creates a lower bound; route inflation, queues and sequential exchanges add more. Connection reuse, TLS resumption and QUIC can reduce setup round trips, so “none can be skipped” is false. An edge hit avoids the origin journey; an uncacheable request still pays the edge-origin path and origin work. The best design depends on traffic and existing connection reuse.

A reference curl -w timing collection can report DNS, connect, TLS, time-to-first-byte and total time. These fields are cumulative milestones. Subtracting time_appconnect from time_starttransfer includes request transfer, proxy/network delay and server processing—not origin CPU time alone. Compare equivalent requests and record cold/warm DNS, connection, TLS and object state; aggregate percentiles from samples rather than averaging independent p95s.

# Reference only; use an authorized test endpoint in a separate integration run.
curl -s -o /dev/null -w 'dns:%{time_namelookup} connect:%{time_connect} tls:%{time_appconnect} ttfb:%{time_starttransfer} total:%{time_total}\n' 'https://example.com/'

Failure scenarios and policy tradeoffs

A shared-key personalized response can disclose one user's data to another. Defense includes explicit origin policy, edge bypass/key review and two-user/anonymous negative tests. This is a generic risk, not an asserted account of Steam's exact private configuration. An edge parser or transformation bug can contaminate outputs; stage changes, minimize sensitive processing and plan downstream purge/incident response. No unsupported claim that a vendor rewrote its parser in a particular language is needed.

For a stale homepage, determine which copy is stale: browser, edge, shield or origin. Long TTL plus forgotten purge is a plausible cause, but so are stale source replicas and references to old asset URLs. Prefer immutable public build assets with stable bytes; mutable HTML discovers new versions. Long edge TTL with reliable purge can fit infrequent CMS writes, while short freshness can fit rapid change. Neither “all build assets must be immutable” nor “long edge TTLs are always safe” covers emergency revocation and operational failure.

Normalize cache keys only after proving equivalence. A missing meaningful query dimension corrupts results; excessive irrelevant variants reduce reuse. Inspect actual response headers and provider cache-status reasons instead of assuming a framework always emits no-cache. no-cache still allows stored validated responses; a conditional hit and an unconditional hit are different metrics.

Recall and worked answers

1. max-age versus s-maxage

max-age is general freshness lifetime; s-maxage applies to shared caches and overrides it there under RFC 9111. A browser can use 60 seconds while the shared cache uses 600, subject to other directives and platform policy. It is not CDN-only.

2. New immutable bundle version

Publish new bytes under a new content-hashed URL and update the referencing HTML/manifest. Keep old assets for ongoing sessions and rollback. A timestamp-changing /static/app.js violates immutable semantics even if its header says otherwise.

3. Vary and content negotiation

Vary identifies request fields used to choose the representation. For encoding, return correct Content-Encoding and vary/normalize as the actual platform requires; for language, keep separate selected representations. Vary cannot repair an origin that generates the wrong body or a provider configured to ignore the required dimension.

4. Authenticated caching risk

A URL-only key can reuse one user's response for another. Our policy bypasses account/authenticated traffic and sends private/no-store. Set-Cookie alone is not a standards-level prohibition; a provider-specific default is not a substitute for the declared policy.

5. Origin shield

It aggregates edge misses and may coalesce identical simultaneous fetches. Its hit rate is conditional on traffic reaching it. Variants, multiple shields, failures and uncacheable requests prevent a universal “200 misses become one” promise.

6. no-cache versus no-store

No-cache permits storage but requires successful validation before reuse as specified. No-store prohibits storage under the directive, not just disk writes, and cannot force deletion from all prior consumers. Use explicit privacy/access controls as well.

7. Why short-lived HTML?

It selects the current asset URLs. Long-lived immutable bundles can remain valid while the HTML/manifest changes quickly. Rollouts must preserve compatible references and old assets; refreshing HTML does not justify mutating old immutable bytes.

8. Unexpectedly low hit ratio

Check eligibility/response policy and status, auth/cookies/provider overrides, then key cardinality/variants and eviction. Separate requests from bytes and revalidated from fresh hits. The target 95% was a workload hypothesis, not a product guarantee.

9. Tag purge

Associate related representations with a product-specific tag and invalidate the affected group instead of enumerating every URL. Confirm support, scope and variant behavior; Workers local deletion is not global purge. Browser copies remain outside ordinary CDN purge reach.

10. Public catalogue stretch

Choose public, max-age=30, s-maxage=300 for an explicitly five-minute-tolerant informational view, a representation ETag, and only genuine variant fields. On a product mutation, purge all affected page/tag representations and account for pagination membership changes, not only pages previously containing that product. Use source validation for checkout inventory. Add stale serving only if its hard age/error conditions are acceptable; do not promise day-old inventory is safe or that stale directives override must-revalidate/s-maxage restrictions universally.

Explain-out-loud test

Compute conditional shield hit ratio, distinguish storage from freshness, trace a two-user key collision and explain why edge purge does not revoke a browser copy. For a performance claim, state the workload, protocol, geography and percentile measurement.

Connections and sources

Load balancing supplies proxy/routing behavior, cache-aside supplies copy lifecycle, and observability supplies per-tier latency/hit/byte metrics. Security work supplies auth isolation and incident response. Programmable edges can combine cached public fragments with personalized work, but those fragments need reviewed keys and cannot make the private result automatically shareable.

Historical source captures dated 2026-10-08 include RFC 9110/9111, RFC 5861/8246, Varnish 7.5 docs and tagged built-in VCL, plus mutable Cloudflare docs. Offline cache/validator/purge fixtures were executed; actual Varnish compilation/runtime, provider configuration, global purge, TLS, browser behavior and performance remain unexecuted.

Reading route, resources and session context

The original session is M07 · Systems & Infrastructure, S064, SYS. Its original 90-minute label is approximate: intuition (5), visual walkthrough (15), hands-on (25), failure analysis (15) and recall (10) sum to 70 minutes; adding the suggested 25-minute pre-read gives 95, not 90. These are planning estimates, not measured completion times; the optional service lab can take longer. Choose one introduction and the relevant reference passages rather than adding all resource durations.

The six original resource recommendations remain available for their distinct functions. Video title/channel/duration claims below are historical labels, not verified playback or endorsements. In particular the same RI9np1LWzqw URL was assigned two incompatible identities; it cannot be asserted to be both without checking it.

Original resource and exact destinationPreserved learning function and qualification
What is a CDN and How Does it Work? — originally ByteByteGo, 7 minOptional visual introduction to PoPs and hierarchy; “clearest” is subjective, identity/duration unverified.
CDN Deep Dive — How the Edge Actually Works — originally Hussein Nasser, 40 minOptional deeper routing/TLS/shielding watch; attribution conflicts with the next entry; speed and duration are learner choices.
What Is A CDN? How Does It Work? — originally ByteByteGo, 20 minOriginal hands-on recommendation retained separately; not verified as a provider click-path or as this title/channel. Use the version-bounded Varnish reference above for the actual exercise.
HTTP Caching — original 20-min estimateReadable companion for freshness, ETag and Vary; the RFCs govern normative claims.
Introducing Argo — original 10-min estimateVendor explanation of routing toward origin, not a guarantee of current product performance or pricing.
Netflix Open Connect traffic steering — original 15-min estimateLarge-scale delivery/routing case study; historical link retained, present reachability/content not independently validated here.

Original incident reading remains distinct from claims: Steam reporting is secondary reporting, not proof of the private VCL configuration; Cloudflare's parser incident report is the operator's account, not support for the former unverified memory-safe rewrite claim. The generic failure analysis above retains the engineering lessons without inventing incident details.

Connections. S062 explains the origin load-balancer hop; S063 supplies copy lifecycle/invalidation; S068 applies delivery/routing through cloud products; S077 connects cache policy to measured web performance; S085 connects edge filtering with origin exposure and DDoS limits. The original S095 “edge compute” label is not reliable curriculum identity: retain edge-fragment assembly as the conceptual follow-up, without misrouting readers to a lesson merely because its number matches.

Navigation: previous S063 · Caching strategies; next S065 · Docker; hub The 6-Month Learning Plan. These links preserve the reading route, not an assertion of site-wide review approval.

Part of the original 130-session evergreen series. Route: intuition → visual → hands-on → production failure analysis → recall. The 90-minute duration is an estimate, not a guarantee.

Current source and verification boundary

Fresh body review: 10 October 2026. The following official primary sources were saved as raw and canonical bytes with exact supporting quotations in the batch-37 evidence packet. Docker documentation is pinned to a repository commit, not a claim that every Engine 28+ release behaves identically; Kubernetes sources are pinned to the release-1.34 documentation branch commit, not to a running cluster. RFC numbers and the OCI/Varnish tags identify their respective contracts. Historical package/image tags in the examples remain reference inputs, not current vulnerability approval.

Only the stated CPU models and static source/syntax checks are evidence from this review. No container, image build, Varnish listener, provider purge, Kubernetes cluster, browser application rendering or site deployment was executed. Preserved resource links are reading recommendations; videos and unverified historical pages are not evidence of a runtime result.

Pause / Recall / Apply

Can you explain it without the page?

Close the example. Reconstruct the core idea, then change one assumption. Mark complete when you’re ready; you can always undo it.

Stored in this browser only. No account, no sync. Clearing browser data removes your record.