HTTP caching headers: Cache-Control, ETags and deploying without stale files
Read and write Cache-Control (max-age, s-maxage, no-cache vs no-store, private, immutable, stale-while-revalidate), validate with ETag and 304, understand heuristic freshness and Vary, and ship new JavaScript safely.
Comes up in: Web fundamentals, Recruiter screen, Frontend system design
Learn#
After every deploy, some of Pooja’s users see a blank page for a day. Their browsers kept yesterday’s index.html, which points to a JavaScript file the new deploy deleted.
Cache-Control tells every cache what it may do. A cached copy is fresh for max-age seconds. While fresh, it is used with no request. Freshness ends, then the cache must ask the server again. The safe deploy pattern is two rules:
# index.html: always check, cheap when unchanged
Cache-Control: no-cache
ETag: "v42"
# /assets/app.3f9a.js: the name changes when the content changes
Cache-Control: public, max-age=31536000, immutableValidation asks “has it changed?” with the saved ETag (If-None-Match) or date (If-Modified-Since). If not, the server sends 304 Not Modified with no body.
Network
- GET / → 200 (24 KB)
- ETag: "v42"
Cache
- / (stored, must revalidate)
The first visit downloads index.html with Cache-Control: no-cache and ETag: "v42".
Read the steps as text
- The first visit downloads index.html with Cache-Control: no-cache and ETag: "v42".
- The second visit: no-cache means "check first". The browser sends If-None-Match: "v42".
- Nothing changed, so the server answers 304 Not Modified with no body. The cached copy is used.
- The HTML links app.3f9a.js, cached with max-age=31536000, immutable. It is used with no request at all.
Predict#
Predict first
What does Cache-Control: no-cache mean?
no-cache allows storing but requires revalidation before each use, which is cheap with ETags. no-store is the one that forbids storing. The names are confusing, which is why this is a favorite screening question.
Interview angle#
Say it like this — about 30 seconds
“No-store forbids caching. No-cache allows storing, but the copy must be checked before each use. An ETag names a version. The browser sends it back in If-None-Match, and the server answers 304 with no body if it still matches. To deploy safely, I give hashed files a long max-age, and the HTML no-cache. Then new HTML points to new files. Stale-while-revalidate serves a slightly old copy while it fetches a fresh one.”
Follow-up What is the difference between no-cache and no-store?
Follow-up How do ETags work?
Follow-up How do you deploy new JS without users getting stale files?
Practice#
Guided
Compute freshness lifetimes the way caches do, and answer conditional requests with 304 or 200.
Done when
s-maxagewins for shared caches;max-agebeatsExpires; heuristics apply only when nothing is set.no-store,no-cacheandprivate(for shared caches) give 0.conditionalResponsehandles lists,*and weak ETags.
Remember#
Try to answer each card before you open it. Then add them to your reviews.
no-cache vs no-store?
no-cache: store but revalidate before use. no-store: never store.
What does a 304 response mean?
Not Modified: use your cached copy; no body is sent.
What does s-maxage control?
Freshness in shared caches such as CDNs, overriding max-age there.
Which Cache-Control fits a content-hashed JS file?
public, max-age=31536000, immutable
What does stale-while-revalidate=60 allow?
Serving a stale copy for up to 60 s while refreshing in the background.
Go deeper
Four layers. Stop at the one your interview needs; each ends with a quick check.
The core ideaEvery round
public lets shared caches (CDNs) store it; private allows only the browser. s-maxage sets the lifetime for shared caches only. immutable says “never revalidate while fresh”: Firefox and Safari use it; Chrome ignores it.
Check yourself: Who may store a response marked private?
Only the browser's own cache, not CDNs or proxies.
How it works underneathSenior rounds
max-age or Expires, caches may guess. A common heuristic is 10% of the time since Last-Modified, so a file unchanged for 10 days may be cached for a day without asking Source: RFC 9111: Calculating heuristic freshness.Check yourself: When does heuristic freshness apply?
When a cacheable response has no max-age or Expires; caches often use 10% of its age since Last-Modified.
Edge cases and trapsWhere people slip
Accept-Encoding, so caches store separate copies. Vary: Cookie or User-Agent splits the cache into thousands of copies, so hit rates collapse.Check yourself: Why is Vary: Cookie dangerous at a CDN?
Every cookie value becomes its own cache entry, so the cache barely hits.
In productionStaff-level answers
stale-while-revalidate serves the old copy at once while refreshing; stale-if-error serves it when the origin fails. Both are great at the CDN for API data that can be a minute old Source: MDN: HTTP caching.
Check yourself: What does stale-if-error do?
Lets a cache serve a stale copy when the origin returns an error.
Finished the five steps? Mark it, and its cards join your reviews.
Last checked 2026-11-01. Spot a mistake? Use “Report an error” below — fixes are listed on the corrections page.
Interview questions this answers
- What is the difference between
no-cacheandno-store? - How do ETags work?
- How do you deploy new JS without users getting stale files?
- What does
stale-while-revalidatedo?