Configurable CDN cache TTLs + purge-on-publish#746
Conversation
- CACHE_CDN_MAX_AGE / CACHE_STALE_WHILE_REVALIDATE env vars, defaulting to the current hardcoded values (300 / 604800) so no site changes behavior without opting in - Netlify-Cache-Tag on cached responses; TinaCMS saves and deletes purge the tag via purgeCache, so publishes are visible immediately regardless of TTL; a failed purge never fails the save - tests for header defaults, env overrides, tag, and DISABLE_CACHE
✅ Deploy Preview for padp-staging ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
✅ Deploy Preview for juel-ancestry ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
✅ Deploy Preview for marronage-staging ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
✅ Deploy Preview for pss-scavenger-hunt ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
✅ Deploy Preview for juel-life ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
✅ Deploy Preview for juel-staging ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
✅ Deploy Preview for relnet-staging ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
|
We tested this on the padp-staging deploy preview, against the published develop deploy as a baseline. Staging previously had DISABLE_CACHE=true, so caching was off entirely; we removed that first so the baseline matches production's normal five-minute caching. While the cache is fresh, the two behave the same: repeat requests come back from the CDN in under 100 ms. The difference shows up after five minutes. The baseline's cached copy expired on schedule and requests went back to the server. The preview, built with CACHE_CDN_MAX_AGE=86400, was still served from the CDN a few minutes later. The longer cache lifetime works. One part can only be tested after this merges: clearing the cache when an editor publishes. The cache-clearing API only accepts a token that Netlify provides to deployed functions, not personal tokens, so I couldn't call it from outside. Once staging's published deploy includes this change, saving a page in TinaCMS will show whether the cache clears right away, and whether our function receives that token automatically or the site needs it set by hand. |
Closes #744.
Two changes, both inert until a site opts in:
Configurable TTLs.
CACHE_CDN_MAX_AGEandCACHE_STALE_WHILE_REVALIDATEenv vars feed theNetlify-CDN-Cache-Controlheader, defaulting to the current hardcoded values (300 / 604800) — with no env vars set, the emitted headers are byte-identical to today's. Browser-facingCache-Controlis unchanged.Purge-on-publish. Cached responses now carry a
Netlify-Cache-Tag, and TinaCMS saves/deletes callpurgeCachefor that tag after the GitHub write (tina/git-provider.ts), so a publish is visible in seconds regardless of TTL. A failed purge logs and never fails the save; local dev never purges (GitHubProvideronly exists when not local). This is what makes a long TTL safe: the plan is to trialCACHE_CDN_MAX_AGE=86400on one production site and measure against the baselines taken today.Record-detail islands set no cache headers, so live FairData content is unaffected by any TTL.
Tests: new
test/cacheControl.test.ts(defaults byte-identical, env overrides, tag present,DISABLE_CACHEshort-circuit); full vitest suite green (69 passed).One thing to validate on staging before any site opts in: whether
purgeCachepicks up an ambient token in our v1-style function; if it 401s, the site needsNETLIFY_PURGE_API_TOKENset (will document either way).