Hosting & Servers

Browser caching: Cache-Control and ETag in practice

Choose cache policies for assets, HTML and account responses; test Cache-Control and ETag, then verify version changes and rollback.

Hosting & Servers

Choose a cache policy for each response

Browser caching can reduce repeated transfers, but a hashed CSS file and an account page need different policies. Start with the response type, its freshness requirements and whether it contains personal information. Configure the relevant path, then verify the response received by the browser rather than assuming a server setting took effect.

The directives that change the decision

  • max-age sets a freshness lifetime in seconds.
  • s-maxage sets the shared-cache lifetime, overriding max-age there. Browsers ignore s-maxage; they do not discard max-age because it is present.
  • no-cache allows storage but requires validation before reuse.
  • no-store tells HTTP caches not to store the response.
  • private prevents storage by shared caches; it does not prohibit storage in the browser.

See the MDN Cache-Control reference for directive semantics. Private alone does not stop sensitive information being stored on the user's device.

Three examples with different purposes

# Public asset whose content never changes at this URL: app.a81c9.css
Cache-Control: public, max-age=31536000, immutable

# Public HTML that must be checked before reuse
Cache-Control: no-cache

# Account or order response that must not enter an HTTP cache
Cache-Control: private, no-store

These are policy examples, not a universal configuration. Immutable applies while a response is fresh; it does not mean that an expired response must never be validated. Use it only when updating the asset also changes its URL. A version in a filename or query string must actually change, and the CDN must include that version in its cache key.

Images and fonts need the same discipline. A font changing infrequently does not justify a year-long immutable policy on a mutable URL. Do not publicly cache HTML containing session-specific content. A CDN cannot make that content safe to share.

ETag, revalidation and 304 responses

An ETag identifies a representation. A client can send the previous value in If-None-Match; if the representation has not changed, the server can return 304 without its body. That still involves a network round trip. Last-Modified and If-Modified-Since provide another validation mechanism, so ETag is not mandatory for every resource.

A fresh response can be reused from memory or disk without contacting the server. There is no fixed sequence of “second visit: 304; third visit: no requests.” A displayed 200 status alone also does not prove that caching failed: inspect transferred bytes and the reported source.

A repeatable check

curl -sS -D - -o /dev/null https://example.com/assets/app.a81c9.css
curl -sS -D - -o /dev/null -H 'If-None-Match: "ETAG-FROM-FIRST-RESPONSE"' https://example.com/assets/app.a81c9.css

Replace the example URL with your asset and copy the actual ETag, including its quotes, into the second command. These GET requests retain headers and discard the body; this avoids assuming that HEAD behaves identically. Expect 304 only if the resource is unchanged and the server implements conditional requests.

  1. Turn off “Disable cache” in DevTools and capture a first visit.
  2. Navigate again using the same profile. Compare transferred bytes, Cache-Control, Age and memory/disk cache indicators.
  3. Publish a test asset at a new URL and check that HTML references the new version.
  4. Compare the final CDN response with origin behavior when they differ.

Incognito does not universally disable caching; it uses separate session storage. A hard reload and DevTools' Disable cache option change test conditions. Neither a missing Age header nor Age: 0 is sufficient to diagnose browser caching.

Deployment and rollback

Record the existing headers and one sample URL before changing anything. Scope long caching to known public assets. Publish the new asset before the referencing HTML, and retain old assets long enough for previously cached pages. If personalized content was served from a shared cache, bypass caching for that path and purge the stored response. Changing future response headers does not remove an existing cached copy.

What caching does not fix

Browser caching does not necessarily fix slow HTML generation, first-visit font loading or long JavaScript tasks. There is no guaranteed percentage improvement. Compare cold and warm visits, transferred bytes and LCP separately. Continue with slow website diagnosis and real-user performance measurement to find the remaining bottleneck.

ServerNet Support

ServerNet engineering & editorial team — specialists in infrastructure, networking and web hosting.

Linux Hosting
Share:

Comments 0

No comments yet — be the first!

Leave a comment

Related service

Linux Hosting

PHP & MySQL hosting on NVMe RAID-10 with LiteSpeed — the solid base for any website, from personal blogs to enterprise Laravel apps. At a price competitors can't explain.