Disk caches (RAM is expensive, disk is cheap)#
By default (TENANT_CACHE_DIR) every cache slot of every mounted WebSite
— rendered HTML, the deps index, templates, data documents, setup/meta docs
and asset bytes — is a DiskCache (drop-core-server/lib/cache/disk_cache,
built by src/disk_caches.ts) instead of the in-memory defaults. A mounted
store then holds no cached content in RAM (only its SDK session / object
state); the fleet's memory footprint stays flat regardless of store count,
and warm content survives restarts (a redeploy's first requests are disk
hits, not re-renders — only deploy-changed output re-renders via the TTLs).
The layout mirrors the platform's refs under {dir}/{env}/{sid}/:
render/{locale}/{collection}/{id}.html rendered pages
deps/{locale}/{collection}[/{id}].json reverse dep index
schemas/{schemaId}/templates/{v}.json template versions
data/{locale}/{collection}/{id}.json hook-warmed documents
meta/{path under store/{sid}/}.json setup docs (+ #mask suffix)
fallback/{path under store/{sid}/}.json last-good meta copies (no TTL; read only on a failed core read)
assets/{storage subpath} raw asset bytes (+ .meta.json)
edge/{m|fn}/{id}/{gen}/{locale}/{req}.json cached /m + /fn GET answers (16 MiB, 1 h)
services/{serviceId}/{key}.json drop.cache of the store's services (8 MiB, 24 h)Every slot's TTL comes from the same resolver as the WebSite cache it backs
(feedTtlMs behind the hook-key gate), so disk and memory never disagree;
meta misses carry their own 60 s __until stamp inside the slot.
Hook-driven invalidation is unchanged (same Cache seam). Extra wiring:
deprovision wipes the store's directory; a credential/domain change wipes
render + deps only (cached HTML embeds the canonical base URL and would
otherwise survive the WebSite rebuild); /-/mount {flush: true} wipes
every slot of the store. Budgets are per-store caps, not
preallocations — ephemeral machine disk is fine, no Fly volume needed.