Cache-Control and revalidation

Play this lesson

Two caching bugs in one week

Kai ships a fix for the shard physics. Some players keep the old, buggy file for a whole week. Meanwhile, others download 4 MB of the same art on every visit.

Both bugs come from one place. A cache is a saved copy that gets reused instead of fetched again. The Cache-Control header, sent with every file, tells browsers and CDNs what they may keep and for how long.

The directives

Quick check

Cache-Control: no-cache means "never save this file".

Show the answer

False

no-cache means the copy may be saved, but must be checked with the server before every reuse. "Never save it" is no-store.

Checking a copy: ETag and 304

When a copy is stale, or marked no-cache, the browser asks before reusing it. The server gave the file an ETag, a short label that changes whenever the contents change, like "a1b2".

The browser sends If-None-Match: "a1b2". If the file is unchanged, the server answers 304 Not Modified with no file attached, and the saved copy is reused. Last-Modified does the same job with a date, but web.dev recommends ETag as more accurate.

Names that change with the contents

Our build tool puts a short hash of each file's contents into its name: shard-physics.3f9c1a.js. Change one letter of the code, and the name changes. A new name is a new address, so no cache can serve the old file by mistake.

That makes long caching safe: max-age=31536000, immutable. 31,536,000 seconds is one year. immutable, from RFC 8246 (2017), says the file will never change while fresh, so browsers skip even the check.

Fix the header

cache rules
/index.html  Cache-Control: ???/assets/* (hashed names)  Cache-Control: ???

The HTML names the hashed asset files. Which pair should Kai ship to fix both bugs?

  1. HTML: no-cache. Assets: max-age=31536000, immutable
  2. HTML: max-age=31536000, immutable. Assets: no-cache
  3. Both: no-store
Show the answer

HTML: no-cache. Assets: max-age=31536000, immutable

The HTML is checked on every visit, so players always learn the newest file names. The hashed assets never change, so they are kept for a year. no-store everywhere would make every visit download everything again.

Stale while revalidate

Some data changes often but must still open instantly, like Shard Garden's "Featured levels" list from the level editor community.

max-age=600, stale-while-revalidate=30 is the example in RFC 5861. The copy is fresh for 600 seconds. For 30 seconds after that, a cache may still hand over the old copy at once while it fetches a new one in the background. After 630 seconds, the next request has to wait for the check.

Quick check

The "Featured levels" list updates every few minutes and must open instantly. Which header fits best?

  1. max-age=60, stale-while-revalidate=300
  2. no-store
  3. max-age=31536000, immutable
Show the answer

max-age=60, stale-while-revalidate=300

The list is fresh for a minute, then a slightly old copy can still open instantly while the new one loads. no-store makes every open wait, and immutable would keep last year's list.

Private things stay private

Bolt says: Next: compression, which shrinks every text file before it travels.

Fact-checked 11 October 2026