v2.10.0 (LTS)
This release is marked for LTS under the v2026.1 LTS Policy for the GraphOS Runtime. It will be supported until September 30, 2026 with patch updates.
Response caching is now Generally Available (GA) and ready for production use!
Response caching enables the router to cache subgraph query responses using Redis, improving query latency and reducing load on your underlying services. Unlike traditional HTTP caching solutions, response caching provides GraphQL-aware caching at the entity and root field level, making cached data reusable across different users and queries.
For complete documentation, configuration options, and quickstart guide, see the response caching documentation.
@cacheControl directives or Cache-Control response headers@cacheTag and invalidate specific cache entries via HTTP endpoint when data changesThe router caches two kinds of data:
By @bnjjj in https://github.com/apollographql/router/pull/8678
Read-only queries are now sent to replica nodes when using clustered Redis. Previously, all commands were sent to the primary nodes.
This change applies to all Redis caches, including the query plan cache and the response cache.
By @carodewig in https://github.com/apollographql/router/pull/8405
The router's HTTP/2 header size limit configuration option now applies to requests using TCP and UDS (Unix domain sockets). Previously, this setting only worked for TLS connections.
By @aaronArinder in https://github.com/apollographql/router/pull/8673
Previously, the response cache invalidation endpoint was only enabled when global invalidation was enabled via response_cache.subgraph.all.invalidation.enabled. If you enabled invalidation for only specific subgraphs without enabling it globally, the invalidation endpoint wouldn't start, preventing cache invalidation requests from being processed.
The invalidation endpoint now starts if either:
response_cache.subgraph.all.invalidation.enabled: true), ORThis enables more flexible configuration where you can enable invalidation selectively for specific subgraphs:
response_cache:
enabled: true
invalidation:
listen: 127.0.0.1:4000
path: /invalidation
subgraph:
all:
enabled: true
# Global invalidation not enabled
subgraphs:
products:
invalidation:
enabled: true # Endpoint now starts
shared_key:
By @bnjjj in https://github.com/apollographql/router/pull/8680
Previously, the router attempted to connect to Redis for response caching regardless of whether response caching was enabled or disabled. This caused unnecessary connection attempts and configuration errors even when the feature was explicitly disabled.
The router now ignores Redis configuration if response caching is disabled. If response caching is configured to be enabled, Redis configuration is required, and missing Redis configuration raises an error on startup:
Error: you must have a redis configured either for all subgraphs or for subgraph "products"
By @bnjjj in https://github.com/apollographql/router/pull/8684
Coprocessor context keys deleted in a previous stage no longer reappear in later stages.
By @rohan-b99 in https://github.com/apollographql/router/pull/8679
You can now customize cached responses using Rhai or coprocessors. You can also set a different private_id based on subgraph request headers.
Example Rhai script customizing private_id:
fn subgraph_service(service, subgraph) {
service.map_request(|request| {
if "private_id" in request.headers {
request.context["private_id"] = request.headers["private_id"];
}
});
}
By @bnjjj in https://github.com/apollographql/router/pull/8652
The DIY Dockerfile now pins the Rust builder to the Bookworm variant (for example, rust:1.91.1-slim-bookworm) so the builder and runtime share the same Debian base. This prevents the image from failing at startup with /lib/x86_64-linux-gnu/libc.so.6: version 'GLIBC_2.39' not found.
This resolves a regression introduced when the rust:1.90.0 bump used a generic Rust image without specifying a Debian variant. The upstream Rust image default advanced to a newer variant with glibc 2.39, although the DIY runtime remained on Bookworm, creating a version mismatch.
By @theJC in https://github.com/apollographql/router/pull/8629
The apollo.router.operations.response_cache.fetch.error metric was out of sync with the apollo.router.cache.redis.errors metric because errors weren't being returned from the Redis client wrapper. The response caching plugin now increments the error metric as expected.
By @carodewig in https://github.com/apollographql/router/pull/8711
http.client.request.body.size metric correctly (PR #8712)The histogram for http.client.request.body.size was using the SubgraphRequestHeader selector, looking for Content-Length before it had been set in on_request, so http.client.request.body.size wasn't recorded. The router now uses the on_response handler and stores the body size in the request context extensions.
By @rohan-b99 in https://github.com/apollographql/router/pull/8712
http.server.response.body.size metric correctly (PR #8697)Previously, the http.server.response.body.size metric wasn't recorded because the router attempted to read from the Content-Length header before it had been set. The router now uses the size_hint of the body if it's exact.
By @rohan-b99 in https://github.com/apollographql/router/pull/8697
Interface objects can be entities, but response caching wasn't treating them that way. Interface objects are now respected as entities so they can be used as cache keys.
By @aaronArinder in https://github.com/apollographql/router/pull/8582
The router now validates propagator configuration and emits a warning log if:
By @rohan-b99 in https://github.com/apollographql/router/pull/8677
Fetched April 11, 2026