Basic

Cache headers and the token

A cached file costs almost nothing on the second visit. The whole skill is naming the file so that a changed file gets a new name, and then telling the browser the old name will never change again.

What you will see

Not immutable, or no long cache. An immutable HTML page serves stale content after every deploy.

About 1 min of reading

Try It

Prove a cache hit and a token bump

1

Read the header

curl -s -D - -o /dev/null http://localhost:3000/public/css/main.css?v=20261010 | grep -i 'cache-control'

Before you run it, say out loud what it will print. Then open the answer.

What it prints
A max-age line. If it is missing or short, the asset is re-requested on every visit.
2

Request twice

curl -s -o /dev/null -w '%{size_download}' http://localhost:3000/public/css/main.css?v=20261010; curl -s -o /dev/null -w '%{size_download} %{from-cache}' http://localhost:3000/public/css/main.css?v=20261010

Before you run it, say out loud what it will print. Then open the answer.

What it prints
The second request should report a cache hit with zero transferred bytes.
3

Bump the token after an edit

grep -n 'main.css?v=' views/partials/head.ejs

Before you run it, say out loud what it will print. Then open the answer.

What it prints
The token line. Change the value in the same commit as the CSS edit, never in a later one.
4

Check HTML is not immutable

curl -s -D - -o /dev/null http://localhost:3000/ | grep -i 'cache-control'

Before you run it, say out loud what it will print. Then open the answer.

What it prints
Not immutable, or no long cache. An immutable HTML page serves stale content after every deploy.
Never put a far-future cache on a URL that has no token in it. That URL will serve the old file to everyone who visited once.

Data Flow

Edit to a new URL
1 Edit the file
↓
2 Bump the token in the URL
↓
3 Browser requests the new URL
↓
4 Old URL stays cached and is never re-requested
Why this works
The two header sets

Tokened assets: far-future immutable. Everything else: short, or revalidate with an ETag. Two sets, and every response picks one.

How to verify a hit

Request twice and compare the transfer size. A hit transfers zero bytes, which is the only proof that the header worked.

Examples

Immutable plus a token

Cache-Control: public, max-age=31536000, immutable on a URL that contains a version token. The token is the thing that changes when the file changes.

The token must change on edit

Edit the CSS and forget the token and the browser serves the old file for a year. Every performance win becomes a correctness bug, which is why the token is a build step, not a habit.

HTML is the opposite

HTML changes on every deploy and must not be immutable. Give it a short cache or revalidation, and keep the long cache for the tokened assets only.

Words this lesson uses

Each one is defined here on this site. Open the entry for the full definition and the other words it points at.

← Request count versus file size
Previous Lesson
Request count versus file size
Next Lesson
Images: size, format, and dimensions
Images: size, format, and dimensions →