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

  1. Set cache_control_policy.enabled: true in your router configuration. Define a global default value, for example max-age=180, public.
  2. Add per-subgraph overrides where specific policies are needed. A pricing subgraph might get no-cache; a static content subgraph might get max-age=3600, public.
  3. On each request, the router collects Cache-Control headers from all subgraph responses involved in the query.
  4. The restrictive algorithm runs: no-cache and no-store take priority over everything. The smallest max-age value wins. The earliest Expires header is used.
  5. GraphQL mutations automatically receive Cache-Control: no-cache when a global policy is enabled, regardless of subgraph settings.
  6. 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.