Cache Control for Federated GraphQL | Cosmo by WunderGraph - WunderGraph
Performance · Cache Control
The strictest cache header wins, automatically.
Cosmo evaluates Cache-Control directives from every subgraph and applies the most restrictive policy to the response. Mutations get no-cache. Error responses get no-store, no-cache, must-revalidate. No manual coordination required.
The problem
Cache policies across subgraphs do not coordinate themselves
In a federated graph, each subgraph has different caching requirements. Without coordination, you get stale data, exposed sensitive fields, or missed caching opportunities.
Subgraphs have conflicting cache requirements
Product data might be safe to cache for minutes. Pricing data should never be cached. Without coordination, setting a single policy for the whole graph means either stale data or missed caching opportunities.
Sensitive data can leak into CDN caches
A permissive cache policy on one subgraph can expose sensitive fields to CDN caching when they appear alongside cacheable data in the same response.
Mutations and errors are not always protected
Mutation results and error responses should never be cached. Without automatic handling, they can be served stale by CDNs or browsers.
Our solution
Restrictive by design
The router evaluates Cache-Control directives from every subgraph involved in a response and applies the strictest policy. You set a global default and per-subgraph overrides. The algorithm handles the rest.
How cache policy aggregation works
- Set
cache_control_policy.enabled: truein your router configuration. Define a global default value, for examplemax-age=180, public. - Add per-subgraph overrides where specific policies are needed. A pricing subgraph might get
no-cache; a static content subgraph might getmax-age=3600, public. - On each request, the router collects Cache-Control headers from all subgraph responses involved in the query.
- The restrictive algorithm runs:
no-cacheandno-storetake priority over everything. The smallestmax-agevalue wins. The earliestExpiresheader is used. - GraphQL mutations automatically receive
Cache-Control: no-cachewhen a global policy is enabled, regardless of subgraph settings. - Responses with any errors automatically receive
Cache-Control: no-store, no-cache, must-revalidate.
Before & After
| Before Cosmo | With Cosmo |
|---|---|
| Manual cache header coordination across subgraphs | Automatic restrictive policy aggregation at the router |
| Risk of caching sensitive data when subgraphs share a response | no-cache and no-store always take precedence |
| No automatic handling of mutations | Mutations automatically receive no-cache |
| Error responses served stale from cache | Errors automatically receive no-store, no-cache, must-revalidate |
Algorithm
Restrictive policy rules
no-cache / no-store
Override all other directives. If any subgraph returns either, the response gets that directive.
max-age
The smallest value across all subgraphs and the global default is selected.
Expires
The earliest expiration timestamp wins.
How Cache Control works in Cosmo Router
Configure
Define a global default policy and per-subgraph overrides in your router configuration. The global value sets the baseline; subgraph values narrow it where needed.
Evaluate
On each request, the router collects Cache-Control directives from every subgraph response that contributed to the federated result.
Apply strictest
no-cache and no-store override everything. Among remaining directives, the smallest max-age wins. The earliest Expires header is used. Mutations get no-cache automatically.
Protect errors
If the final response contains any errors, the router sets Cache-Control: no-store, no-cache, must-revalidate regardless of the configured policy.
Capabilities
Policies, overrides, and automatic protection
Global defaults, per-subgraph overrides, and automatic safety for mutations and errors.
Global default policy
Set a baseline Cache-Control value for all responses. Per-subgraph overrides narrow the policy where data requires stricter caching behavior.
Per-subgraph overrides
Configure individual subgraphs with their own cache directives. The restrictive algorithm applies the strictest setting across all subgraphs accessed by a query.
Automatic mutation handling
When a global cache policy is enabled, GraphQL mutations automatically receive Cache-Control: no-cache. Mutation results are never cached.
Error response protection
Responses with errors automatically receive no-store, no-cache, must-revalidate, preventing clients or CDNs from re-serving a stale error response.