CodePark/ questions / Headers & HTTP caching
START PRACTICINGPRACTICE
Backend question · HTTP & API design › Headers & HTTP caching

Design Cache-Control headers for a web app that serves index.html, fingerprinted bundles like app.3f9a2c.js, and a per-user /api/me endpoint.

Give each kind of file a different policy:

  • Fingerprinted bundles: Cache-Control: public, max-age=31536000, immutable.
  • index.html: Cache-Control: no-cache with an ETag.
  • /api/me: private, or no-store if the data is sensitive.

Fingerprinted assets have a hash of their content in the file name, like app.3f9a2c.js. The file at that URL never changes, because a new build makes a new file name. So cache it for a long time (31536000 seconds is one year). immutable tells browsers not to revalidate the file, even when the user reloads the page.

index.html lists those file names. So it must always be current. If it is old, users get an old HTML page that points at old bundles. no-cache does not mean "don't cache". It means "check with the server before every use". The ETag is a version tag for the file. The browser sends it back, and the server usually answers with a small 304 Not Modified. So every load revalidates cheaply.

/api/me contains personal data. A CDN (a shared cache between users and your server) must never store it and serve it to someone else. Use private if the browser may keep it for a short time. Use no-store if it is sensitive, so nothing stores it at all. Some shared caches build their cache key without looking at cookies. So private or no-store is what protects you. Don't rely on the CDN noticing the Authorization header.

  • Hashed assets get a long max-age plus immutable.
  • The HTML entry point uses no-cache with ETag revalidation.
  • Per-user data uses private or no-store, and is never stored in shared caches.
  • Cache busting comes from changing the URL, not from headers.