A render server answers almost every request from its own caches. A cached page stays fresh because the platform pushes every change to the server the moment it is written: the hook feed. Each push evicts or rewarms exactly what it covers. The cache lifetimes (TTLs) are only a backstop for a push that never arrived.
This page lists every write that pushes, every cache a render server keeps with its lifetime, and why those lifetimes can be long.
What each write pushes#
All rows below belong to the server event group, which hosted sites and the managed hook entries subscribe to. Order, invoice and form-record pushes carry personal data, so they are never part of that group.
Write (under store/{sid}/…) |
Event | Payload | Seed label | What the receiving server does |
|---|---|---|---|---|
data/{locale}/{collection}/{id} |
data |
the document, including its _dt / _f stamps (see below) |
{locale}/{collection}/{id} |
rewarms the document in the data cache (with the ordering guard), and evicts the page plus every page that depends on it (all pages for a header or footer doc) |
files/… |
files |
the file document | files/{storage_path} |
evicts the cached asset |
schemas/{id}/templates/{v} |
templates |
a signal {schemaId, version} |
templates/{schemaId}/v{n} |
evicts the template and drops rendered pages |
elements/{id} |
elements |
a signal {id} |
elements/{id} |
evicts the element and drops rendered pages |
setup/web, setup/data, setup/design, setup/elements |
setup |
a signal {id} |
setup/{id} |
evicts that setup doc and drops rendered pages |
the store document (only when locales or name change) |
setup |
a signal {id: '$store'} |
setup/$store |
evicts the store document and drops rendered pages. The server also reads the slug registry's migration stamp from this document; a change of the stamp alone pushes nothing and is picked up within the meta lifetime — until then the server only makes a few extra registry reads, it never serves a wrong page |
slug/{id} |
slug |
a signal {key, locale?} — key is the registry document id: the URL key itself (one document per key, holding a target per language) |
slug/{key} |
evicts that slug entry and the sitemap slug list; pages stay |
routes/{collection}/slugs/{id} |
slug |
a signal {key, collection, locale?} (same key shape) |
slug/{collection}/{key} |
evicts that slug entry and the collection's sitemap list; pages stay |
routes/{collection}/routes/{category}/slugs/{id} |
slug |
a signal {key, collection, category, locale?} — a category's registry (/{segment}/{category}/{slug} URLs); the category also rides as the x-drop-category header |
slug/{collection}/{category}/{key} |
evicts that slug entry and that category's sitemap list; pages stay |
A signal is an id stub, never a document body: it tells the server what to forget, and the next request reads the fresh value. Deletes push the same event with x-drop-deleted: true.
Some writes never push:
- Setup documents outside the four above. These include mail settings, hook configuration, analytics and shipping. Only the setup documents a render server reads can push, and those are exactly the documents the public read endpoint serves. Private configuration never leaves the platform, not even as a signal.
- Schema documents. A render server never reads them (see Schema stamps below). A schema change reaches servers as
datapushes of the documents it affects. - Other collections and data roots. Products, customers, carts, revision history, stock, promo and payments are not render inputs.
Caches on a render server#
The with a hook key column applies to any server that verifies pushes with the store's hook key, which includes every platform-hosted site. A server without a key cannot trust pushes, so it keeps the short defaults in the last column.
| Cache | Holds | With a hook key | Evicted early by | Without a hook key |
|---|---|---|---|---|
| Meta | the public setup docs, the store document, elements, slug entries, the favicon | 4 h | setup, slug, elements |
60 s |
| Meta, not found | a lookup that found nothing | 60 s | the same pushes | 60 s |
| Data | data documents | 4 h | data |
60 min |
| Rendered pages + their dependency index | finished HTML | 4 h | data, templates, elements, setup; also dropped whenever setup/web, setup/data or the store's locales differ from the last render (a backstop that survives a restart) |
30 min |
| Templates | one template version | 4 h | templates |
30 min |
| Assets | file bytes served same-origin | 4 h | files |
60 min |
| Sitemap slug list | the slug registry, for sitemaps — one list per registry (the root one, each routed collection's, each category's) | 4 h | slug (that registry's list); setup of setup/data (all lists) |
60 min |
| Translations | {{t}} strings per locale |
process lifetime | data pushes of translations |
process lifetime |
| HTTP: page HTML | browsers and the edge | 60 s | — | 60 s |
| HTTP: CSS / JS | content-hashed URLs | 1 year (a new hash on every change) | — | 1 year |
Large files are never cached. An object above 16 MiB (a video, a big download) is not relayed by the render server at all: /assets/{storage_path} answers a redirect to the storage URL, decided from the object's size before any byte is read, and storage serves it directly, with byte ranges, so video seeking works. drop-core-server sets the limit with assets.maxObjectBytes; the tenant fleet reads TENANT_ASSET_MAX_OBJECT_MB.
Collection listings are never cached on their own. They are read live and reach a visitor only inside a rendered page, and that page depends on the whole collection, so any data push in the collection evicts it.
drop-core-server exposes all of this as one option: feedTtlMs (default 4 h; 'legacy' keeps the short defaults). Each cache's own option (renderTtlMs, dataTtlMs, …) still wins. The tenant fleet reads the same value from TENANT_FEED_TTL_MS, or from TENANT_FEED_TTL_MS_DEMO / _PROD per environment.
Why 4 hours is safe#
A long TTL is only dangerous when something the page shows can change without a push. The platform guarantees there is no such input:
- Data documents push on every write. A document that does not exist is never cached, so a new one shows up on its first request.
- Lists and query results are not cached separately. A page that lists a collection is evicted by any write in that collection.
- Templates push on every edit. The "newest version" lookup for an unpinned page is never cached, and publishing a version drops rendered pages.
- Translations are patched in place by their own
datapushes. - Site configuration (
setup/web,setup/data, the design system, the element library) and the store's locales and name push asetupsignal. - Slugs in both registries push a
slugsignal, including when a new slug is created. A renamed slug's redirect is resolved per request to the document's current address, so it never goes stale. - Language versions of a page (language in the URL): a page reads its other-language documents for its
hreflanglinks and switcher, and depends on them — renaming the English slug re-renders the Czech page. - Elements and files push
elementsandfiles. - Schemas are never read while rendering: what a page needs from them is stamped onto each document. A schema change re-stamps the affected documents, and each one pushes.
- Nothing a page renders depends on the clock, stock or promotions, so no page goes stale just because time passes.
The remaining risk is a push that is lost (deliveries are best-effort and not retried). Five things contain it:
- "Not found" stays at 60 s. A lost push for a new slug or document can never hide it for hours.
- Pushes are idempotent and ordered. Signals only evict, so a duplicate does no harm. Data pushes carry
x-drop-updated, and an older push never overwrites a newer document. An older push is still allowed to evict the rendered page, and a push that arrives while the same page or document is being read always wins over that read. - The 4 h lifetime needs a hook key. A server that cannot verify pushes keeps the short defaults automatically.
- Memory stays bounded. Every cache has a size cap, and a long TTL means entries leave by eviction instead of by age. Memory and disk use stay flat.
- Failures are visible and fixable. Each hook shows its last delivery status in CRM & Studio (Settings › Advanced › Hooks). Refresh site caches on the web-address card empties one site's caches on every server that hosts it, immediately.
The rule that keeps this true: any new input to a rendered page ships with its own push event, or with its own short TTL.
If a push is lost#
Delivered pushes take effect within seconds. The bounds below apply only when a push never arrives, and Refresh site caches ends any of them at once.
| What changed | Visible after at most |
|---|---|
| A data document, a page or a list that includes it | 4 h |
| A setup document, the store's locales or name, an existing slug, an element | 4 h |
| A template or an asset | 4 h |
| A schema (form rules, date formatting) | 4 h |
| The sitemap slug list | 4 h |
| A new slug or document that was briefly cached as missing | 60 s |
| Page HTML at the edge | + 60 s |
Schema stamps#
A render server needs two things from a document's schema: which values are dates (to localize them) and the contract of any form placed in the document (to validate submissions). Instead of reading schemas, the platform computes both when the document is written and stores them on it:
_dtmaps value paths to their date/time parts. For example,{"published": {"date": true}, "events[].when": {"date": true, "time": true}}, with{"ref": true}marking reference fields so that referenced documents are localized by their own_dt. Every stamped document carries it, even when it is empty._fmaps each placed form's slug to its resolved contract.
Clients cannot set either value: the platform recomputes them on every write. Render servers strip them from template data and from the DROP_DATA bootstrap, so templates and page scripts see the document exactly as before.