Skip to content

Instantly share code, notes, and snippets.

What would you like to do?
Caches All the Way Down

Caches all the way down

Layers of caching in the browser

(kind of Chromium specific here and there)

1. MemoryCache

  • rendering process specific, short-lived
  • strict matching, same resource type, etc, CSP
  • everything (even no-cache, except for no-store)
  • not shown in dev-tools or in Resource Timing
  • not bound to HTTP semantics

2. ServiceWorker

  • explicit API, controlled by the web developer
  • not bound to HTTP semantics

3. HTTP cache

  • yay, made it to the network stack
  • bound to HTTP semantics

4. Push cache

5. network

  • user -> isp -> edge -> internet -> reverse proxy -> origin
  • once got the response:
    • HTTP cache (if cacheable)
    • ServiceWorker can decide to cache
    • resource timing
    • MemoryCache

HTTP caching semantics

  • the URL is the cache key
  • freshness
  • validators:
    • res: ETag, Last-Modified,
    • req: If-None-Match, If-Modified-Since
    • but! 1 RTT penalty
  • scope matters, too: is it private (browser) or a (shared) public proxy


old directives

  • Expires: define date
  • Pragma: no-cache nah, old, abused


  • max-age - in seconds
  • s-max-age - max age for shared proxies,
  • immutable - never revalidate
  • must-revalidate - must revalidate if freshness ran out
  • no-cache - caches but revalidates
  • no-cache=set-cookie - can be cached but ignore header
  • no-store - kind of does what it does
  • proxy-revalidate - must-revalidate for proxies
  • no-transform - e.g image/JS minifying proxies
  • stale-while-revalidate - can serve stale, but revalidate at the same time (fairly new)
  • scope: public/private - user vs public caches
  • by default: can cache (except for URLs with params in old implementations)


  • controls your own public cache, not well-defined, spec not great


  • caching proxies must add this header to cached responses


  • response depends on headers
  • example: image width, encoding, normalized UA


  • creating complex cache keys, with partitions


immutable content

  • Cache-Control: max-age=<year> immutable

always revalidate

  • Cache-Control: max-age=0 must-revalidate

everything else sucks

  • and can be a gamble

but, hold till told

  • CDNs usually use this too
  • providing API to purge

but, Service Workers to the rescue

  • can purge from cache with API
  • e.g. purge based on a refresh list served up somewhere

but, use H2 server push to purge

  • just an idea for now
  • no browser support
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment