Serve unhashed static files no-store, not no-cache - #390
Conversation
#388 switched every static file outside /assets/ to `no-cache`, on the reading that Cloudflare would cache and revalidate at the edge while the browser revalidated with a 304. Half of that is what happens. The edge does revalidate, but the zone's Browser Cache TTL is four hours, and with Origin Cache Control on Cloudflare stamps that on any cacheable response whose own max-age is lower: staging answered `cache-control: max-age=14400` for theme-boot.js and app.css the moment #388 deployed. A browser would sit on a stale copy for four hours after a deploy, and the two smoke probes that assert `no-cache` failed, which skipped the production deploy. `no-store, no-cache` is the form this zone passes through untouched; index.html has been served that way throughout and arrives intact as DYNAMIC. So the unhashed files take the same policy as the page that loads them. The price is that a browser re-fetches them on every visit rather than revalidating, about 450 KB for the data explorer including its vendored libraries, on a low-traffic public page. The smoke probes and the rendered-config test now assert `no-store`. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
|
Claude finished @Babissimo's task in 1m 31s —— View job Code Review
Summary: This is a small, well-scoped fix. Specific checks:
Minor nit (non-blocking): No security, correctness, or performance concerns. The tradeoff called out in the PR description (full re-fetch instead of a 304 on every visit, ~450KB for the data explorer) is reasonable for a low-traffic public page and is the right fix for the stated bug (stale browser cache for up to 4h after a deploy, and the two failing smoke probes in run 34972146296). I was unable to execute |
Why
#388 switched every static file outside
/assets/toCache-Control: no-cache, expecting the edge to cache-and-revalidate and the browser to revalidate with a 304. The edge half holds. The browser half does not: the zone's Browser Cache TTL is four hours, and with Origin Cache Control on (the default on this plan) Cloudflare stamps that on any cacheable response whose own max-age is lower. The moment #388 deployed, staging answeredcache-control: max-age=14400fortheme-boot.jsandapp.css. A browser would sit on a stale copy for four hours after a deploy, and the two smoke probes assertingno-cachefailed in run 34972146296, which skipped the production deploy. The pipeline is red until this lands.What
no-store, no-cachefor the unhashed files, the policyindex.htmlalready has: this zone passes it through untouched (cf-cache-status: DYNAMIC, header intact, verified on staging today). Neither the edge nor the browser keeps a copy, so a deploy shows through at once. The smoke probes and the rendered-config test assertno-store; thespa.confcomment records whyno-cachealone is not enough, as a standing constraint.The price is a browser re-fetch on every visit rather than a 304, about 450 KB for the data explorer including its vendored libraries, on a low-traffic public page. The hashed
/assets/policy is unchanged.Verified
pytest tests/test_nginx_static_cache.py tests/test_nginx_rewrite_ordering.py tests/test_towers_vhost_coverage.py: 10 passed.nginx -ton it innginx:alpine: syntax ok; the rendered config carries theno-store, no-cachedirective twelve times, once forindex.htmland once for the catch-all in each of the six SPA vhosts.pre-commit run --all-filesclean;bash -nand shellcheck (warning level) clean.browser_cache_ttl= 14400, plan Free.Active nodes > 0also failed in run 34972146296; that is the known staging fleet reconnect race, unrelated.After this deploys, the edge still holds copies stored under the old headers until they expire; those get purged by hand once, and the smoke probes bypass them with a never-seen query string.
ClickUp Edge keeps unhashed static files for a week, so a deploy of the data explorer is invisible until purged.
🤖 Generated with Claude Code