Caching and cache-busting

How a nanoesis deploy handles browser and CDN caching, so "publish and it's live" just works, and the one part you control: the filenames of your own static assets.

When you publish, nanoesis writes a fresh static site. The question is how long a browser (or a CDN) is allowed to keep serving the previous copy. Get that wrong and a published change looks stale until someone hard-refreshes. nanoesis sets this for you; here is the whole model.

What nanoesis sets for you

Every published file is written with a Cache-Control header, chosen by what the file is:

  • Pages and other non-fingerprinted files (your HTML, a hand-managed styles.css) get no-cache, which means "check with the origin before reusing a cached copy". Because the origin serves a strong ETag, that check is a cheap 304 Not Modified when nothing changed, and the new bytes the instant something does. No stale window, no hard refresh.
  • Responsive image variants that the media pipeline generates get public, max-age=31536000, immutable, cached hard and effectively forever. That is safe because their filenames are content-hashed: change the image and the filename changes, so the old URL is never reused.

Why a CDN purge is not the whole story

If you front your site with a CDN, nanoesis also purges its cache on publish. That is useful, but it is not the lever that fixes staleness: a purge clears the edge, not a visitor's browser, and most CDNs do not cache HTML at the edge at all. The header is what controls the browser, and it travels on the file itself, so a site served straight from storage with no CDN in front is covered the same way.

The part you control: your own static assets

nanoesis content-hashes the images it generates, so they cache-bust automatically. Files you place in public/, a stylesheet, a script, a font, keep the stable filename you gave them, so they are served no-cache: always correct, but revalidated on every load rather than cached for a year.

If you want your own assets cached hard too, give them content-hashed filenames in your build, for example styles.9f3a1c.css, and reference the hashed name. A changed file then becomes a new URL, which is exactly what makes long-lived caching safe. Until you do, no-cache keeps them correct, just not maximally cached.

On an older nanoesis? A stopgap

Cache-Control on published files works from 0.1.25 (0.1.24 shipped it but a wrapper bug made it a no-op). On an earlier version the files carry no caching header, so a published change can look stale until a hard refresh. If you proxy through Cloudflare, a Cache Rule that sets the browser cache TTL (HTML to no-cache, static assets to a short TTL) bridges the gap at the edge. Upgrading is the real fix; the stopgap only helps sites behind Cloudflare.