Caching · Practical guide

Cache-Control explained: no-cache, no-store and private

A stale page and a cached private response are different problems. Cache-Control helps you describe who may store a response and when it may be reused. Read the policy in the context of the URL: an account screen needs different behavior from a versioned stylesheet.

Separate storage from reuse

no-store instructs caches not to store the response. no-cache permits storage, but requires validation before reuse. private excludes shared caches while allowing a browser cache. max-age specifies a freshness lifetime in seconds. These directives are not interchangeable ways to turn caching off.

A policy can combine directives. For a personalized response, first decide whether storage is acceptable at all. For a public file, decide how long an unchanged copy may be reused. The choice should follow the content and how updates reach users.

Reference: MDN: Cache-Control

Match the policy to the resource

A sensitive account response is a candidate for no-store. A versioned public asset can use a long freshness lifetime if every content change produces a new URL. A public HTML page that changes at the same address needs a strategy for getting those changes to returning visitors.

The examples below describe two different resources. Do not apply the asset policy to all application responses. Even on the same host, an image, a checkout screen and a downloaded invoice may require different rules.

# Sensitive account response
Cache-Control: no-store

# Public asset with a content hash in its URL
Cache-Control: public, max-age=31536000, immutable

Investigate the response users actually receive

If an update appears late, scan the exact resource URL rather than only the homepage. Compare the returned cache policy with the place where you configured it. A CDN may have its own rules, and different routes may use different application middleware.

A header scan does not measure a returning browser session or prove a cache hit. HeaderScan sends no cookies, so it cannot establish the policy of a signed-in account page. Use browser developer tools in your own authenticated session for that check, without sharing session credentials.

Review a caching change

Make the expected result explicit before changing a lifetime. For example: a new stylesheet URL should load immediately after deployment, while an unchanged asset should remain reusable.

  1. Classify the response as public, personalized or sensitive.
  2. Check its current headers on the public endpoint and compare them with your application and CDN settings.
  3. Update the policy and any necessary asset versioning together.
  4. Retest both a fresh visit and a repeat visit; scan the endpoint again to verify the deployed header.

Keep reading

Related guides