Experimental feature. Response caching is in alpha and is subject to change, and should not be used in production environments.
_entities root field to resolve fields of an entity that another subgraph owns. Root field fetches are not cached.
Entries are keyed per entity and per selection set. Asking for different fields of the same entity does not share an entry.
Response caching is disabled by default.
What gets cached
A subgraph response is cached only when itsCache-Control header asks to be. The rules apply in this order:
no-storerefuses caching.no-cacheorprivaterefuses caching, in any form. This includes the qualifiedno-cache="Set-Cookie"form.publicis required.Cache-Control: max-age=60on its own is not cached.s-maxagesets the lifetime and takes precedence overmax-age.max-agesets the lifetime whens-maxageis absent.fallback_ttlsets the lifetime when the response sayspublicand names no lifetime of its own.
0 for s-maxage or max-age refuses caching. It does not fall through to the next rule.
A subgraph that sends no Cache-Control header at all is never cached. fallback_ttl does not apply to it.
A response carrying GraphQL errors is never cached, whatever its Cache-Control header says.
Configuring the response cache does not make anything cacheable on its own. Subgraphs opt in by sending
Cache-Control: public. If nothing appears to be cached, check the subgraph response headers first.Enable it
Redis
Every router replica shares one cache and entries outlive the process. Define a storage provider, then reference it byprovider_id.
provider_id fails startup.
Router memory
Each replica holds its own cache, nothing survives a restart, and no Redis is needed.provider defaults to redis, so caching in memory has to be asked for by name. This prevents a missing provider_id from quietly turning one shared cache into one cache per replica.
Configuration reference
config.yaml
storage is required when enabled is true.
Environment variables bypass the config schema validation. A fallback_ttl of zero or less fails startup either way.
Limitations
These apply to the current alpha. A batch is served from the cache only when every entity in it is present. One miss sends the whole batch to the subgraph, including the entities that were already cached. Entities are stored individually, so a later batch made up only of cached entities is a full hit. Cache hits produce no subgraph telemetry. A hit skips the subgraph fetch, so no subgraph span or metric is recorded for it. Subgraph request counts fall as the hit rate rises. Use them to confirm the cache is working, not to measure traffic.enable_multi_fetch disables response caching. When engine.enable_multi_fetch is on, the router merges entity fetches to the same subgraph within one parallel wave into a single request. Merged fetches are not cached, and nothing reports that they were skipped. Do not enable both and expect response caching.
Observability
The router logs once at startup when the cache is enabled. With the Redis provider:Related
- Storage Providers defines the Redis instance the
redisprovider references. - Cache Warmer is a different cache. It pre-populates the operation plan cache and does not cache subgraph responses.