Response caching
The public GraphQL API caches resolved responses by default. When a record is written, the cached responses that referenced it are dropped.
On by default, for 60 seconds
Every model that holds records caches for 60 seconds. A repeat of the same query inside that lifetime returns the stored response without resolving it again. Ordinary models share one entry between callers who send the same query. Models whose records have an owner are cached per owner.
Invalidation after a write
Creating, updating, deleting, publishing or unpublishing a record drops every cached response that referenced it. A list response is dropped when any record in the list is edited, and unrelated models are untouched. Invalidation runs after the write commits, so for a few milliseconds a read can still get the previous response. The lifetime is the backstop if an invalidation is lost, and if the cache store is unreachable the write still commits and the next read resolves normally.
Tuning and opting out
Lifetime and scope are set per model, in the console or in your config file under cacheControl, and a model can opt out altogether. A single request can force a fresh read with a no-cache header. Mutations and draft reads are never cached.
Reading your own write
A mutation response carries an X-Foir-Write-Token header. Send it on your next read and the server serves a cached entry only if it is at least as new as that write.
Purging by hand
For changes the write path cannot see, foir cache purge clears one record, one model or everything. A refresh mutation covers a single record whose content changed in another system.
Read the detail
The caching guide covers cache scopes, per-model settings, request headers and the shared endpoint for CDNs.