Cache headers for a static site: hashed files forever, HTML never
A cache policy depends on whether the filename changes with the content, not on file size. Long-caching HTML hands users an old entry point that points at deleted chunks.
The first problem a static site shows after launch is not speed. It is a blank page right after a deploy. The cause is almost always the same: the HTML was cached, and the asset filenames it references have changed.
One question decides everything
Does this filename change when the content changes? If yes, cache it forever. If no, revalidate every time. File size and hit rate are irrelevant.
The build output here falls into three groups:
| Path | Filename | Policy |
|---|---|---|
/_astro/* |
content hash | max-age=31536000, immutable |
*.html |
fixed | no-cache |
/pagefind/* |
mixed | max-age=3600 |
Why HTML must not be long-cached
A build is atomic: npm run build writes new hashed filenames and removes the old ones. index.html is the only entry point. If a browser keeps it for a year, the user opens the previous deploy, which references /_astro/index.abc123.js, a file that no longer exists. Structure and CSS render, the script 404s, and every interactive part is dead.
no-cache does not mean do not cache. It means ask again, with ETag, on every navigation. A hit returns 304 with no body; the cost is one round trip, and the payoff is never referencing a deleted hash.
location ~* ^/_astro/ {
add_header Cache-Control "public, max-age=31536000, immutable";
}
location ~* \.html$ {
add_header Cache-Control "no-cache";
}
Two easy misses
- The Pagefind index directory.
pagefind.jscarries no hash while the shards do. One hour for all of it follows a rebuild closely enough without re-downloading megabytes per search. - Conventional entry points like
sw.jsand a manifest. This site has none, because it does not ship a PWA. If it did, they belong in the same group as HTML: fixed filename, no long cache.
Do not ask how big the file is. Ask whether the filename changes when the content does.

Comments
…