Three caches sit in the render path, all keyed on the org theme's CacheVersion:
- Resolved files — Key:
ThemeV2_Files_{orgId}_{version}— Lifetime: 30 min sliding / 2 h absolute — Notes: The merged base+override file dictionary plus extracted section schemas. - Parsed templates — Key:
ThemeV2_Parsed_{orgId}_{version}_{path}— Lifetime: 30 min sliding / 2 h absolute — Notes: Fluid ASTs — parsing is the hot CPU work, so page/layout parse results are memoised. - Rendered pages — Key:
ThemeV2_Page_{orgId}_{path}_{version}+ filter suffix — Lifetime: 5 min sliding / 15 min absolute — Notes: A size-bounded (5,000 entry) dedicatedMemoryCache, because the key includes visitor-supplied filters (_loc{id},_cat{id},_attr{ids},_embed) and an attacker must not be able to mint unbounded entries.
Version bumps are the invalidation mechanism. Every edit through AdminThemeV2Service —file save/delete/reset, section settings, global settings, content, snapshot restore, base themeupdate, reset to default — funnels through BumpCacheVersionAsync, which stamps a fresh GUIDonto CacheVersion and writes an edit-log row in the same commit. A new version means new cachekeys everywhere, so stale ASTs and stale HTML simply stop being addressable.
Builder draft previews (unsaved section/content/global settings passed intoRenderPathAsync) never read or write the rendered-page cache.