Get CV

DevOps

Hashed assets stay, the HTML shell does not

JS and CSS with a content hash get a long max-age. The document that points at those hashes revalidates after every deploy.

A hashed filename is a contract. app.abc12.js will never change. nginx can send a long max-age and the immutable flag. The HTML shell cannot. After a deploy it is the only document that points at the new hashes. A cached shell pointing at deleted files is how returning visitors get a blank page.

Fonts and images now use the same long headers. gzip runs on text types only. Compressing a webp or a woff2 burns CPU and saves nothing.

Hashed assets are immutable. The HTML shell revalidates after every deploy.
Hashed assets are immutable. The HTML shell revalidates after every deploy.

The cookie bypass

Anonymous GET HTML also goes through a short nginx microcache. The key is scheme, host, uri, and locale. Query strings that do not change the page stay out of the key. Requests with auth_token skip that cache. A signed-in user must not receive a public fragment.

JSON under /api stays with PHP. Caching an API response in nginx mixed a list for one locale with a write from another tab.

A signed-in request with auth_token never receives a public fragment.
A signed-in request with auth_token never receives a public fragment.

The check after a build

Load a page. Confirm the shell revalidates. Confirm the referenced JS and CSS come back with the long max-age. A missing Vite manifest is worse than a 500. The page renders with no CSS and looks broken instead of throwing.

The rule is short. Hashed files are immutable. The HTML shell is not. Cookies bypass the shared HTML cache. That is the nginx update on this site.

Back to news