Cache-Control and revalidation
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
- max-age=NThe copy stays fresh for N seconds. While fresh, it is reused without asking.
- no-cacheThe copy may be stored, but must be checked with the server before every reuse.
- no-storeNo cache of any kind may store it.
- private and publicprivate: only the player's browser may keep it. public: shared caches, like a CDN, may too.
- s-maxage=NLike max-age, but only for shared caches. It wins over max-age there.
Quick check
Cache-Control: no-cache means "never save this file".
- True
- False
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
1/index.html2 Cache-Control: ???3/assets/* (hashed names)4 Cache-Control: ???
The HTML names the hashed asset files. Which pair should Kai ship to fix both bugs?
- HTML: no-cache. Assets: max-age=31536000, immutable
- HTML: max-age=31536000, immutable. Assets: no-cache
- 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?
- max-age=60, stale-while-revalidate=300
- no-store
- 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
- Shared cachesA CDN serves one copy to many players. Only send it things that are the same for everyone.
- Personal answersA player's save or inbox gets private or no-store. A response to a request with an Authorization header must not go in a shared cache unless it is marked public.
Bolt says: Next: compression, which shrinks every text file before it travels.
Fact-checked 11 October 2026
- MDN: Cache-Control developer.mozilla.org
- web.dev: Prevent unnecessary network requests with the HTTP Cache web.dev
- RFC 8246: HTTP immutable responses rfc-editor.org
- RFC 5861: HTTP Cache-Control extensions for stale content rfc-editor.org