Performance

Immutable cache

Immutable cache is telling the browser that a fingerprinted file will never change, so it should not even revalidate. The directive is `Cache-Control: immutable`, usually paired with a one-year max-age.

How it is measured

Check the response header and test a normal reload. A reload on an immutable file produces no conditional request in browsers that support the directive, while without it Chrome historically revalidated on reload.

It only makes sense when the URL changes with the content, such as `app.8f3c1.js`. The new deploy changes the name, so the old cached copy is never reused.

Worked example

A site with `main.css` at `max-age=31536000` and no immutable flag shows a 304 request of 48 ms when a user hits reload in Safari. With `immutable`, the same reload makes zero requests and the stylesheet is available at 0 ms.

The team deploys a fix and the new bundle is `app.b19d4.js`. Visitors pick up the new HTML, which points to the new name, and the old file simply stops being asked for.

How it differs

Immutable cache is a promise about one file. Cache-Control is the header that carries the promise. A CDN can also hold the file for a long time. The directive says never revalidate, while a plain max-age says do not ask until it expires.

Common errors

Using immutable on a URL like `/style.css` that you later edit. Forgetting to fingerprint filenames. Adding it to HTML. Believing it purges itself when the file changes. Setting a short max-age with immutable, which makes little sense.

In practice

Fingerprint every build asset, serve it with a year-long max-age and immutable, and keep HTML short-lived. Check on a hard reload that the asset shows no network request.

See also

Cache-Control, Content delivery network

Sources

Count this on a real site.

Watch my website