Response Caching
GraphQL Yoga v4 documentation (superseded by v5): Response caching is a technique for reducing server load by caching GraphQL query operation results.
Response caching is a technique for reducing server load by caching GraphQL query operation results. For incoming GraphQL Query operations with the same variable values, the same response is returned from a cache instead of executed again.
Quick Start
The response cache is a separate package that needs to be installed.
The following sample setup show as slow field resolver (Query.slow).
After starting the server we can execute a GraphQL Query operation, that selects the Query.slow
field.
The output will look similar to the following:
After executing the same curl statement a second time, the duration is significantly lower.
Session based caching
If your GraphQL API returns specific data depending on the viewer’s session, you can use the
session option to cache the response per session. Usually, the session is determined by an HTTP
header, e.g. an user id within the encoded access token.
The session function receives a request parameter that is a
Request object.
Enforce session based caching
In some cases, a type or a field should only be cached if their is a session. For this, you can use
the scope to indicate that the cache should only be used if a session is present.
It is also possible to use the @cacheControl directive to define the scope.
Any query containing a type or a field with the scope PRIVATE will only be cached if a session is
present.
Time to Live (TTL)
It is possible to give cached operations a time to live. Either globally, based on schema coordinates or object types.
If a query operation result contains multiple objects of the same or different types, the lowest TTL is picked.
Using plugin configuration
Using Schema directive @cacheControl
For a schema first approach, the @cacheControl directive can be used to define the TTL.
Notice that the global default TTL can only be define in the plugin options ttl and not via the
directive.
Invalidations via Mutation
When executing a mutation operation the cached query results that contain type entities within the Mutation result will be automatically be invalidated.
For the given GraphQL operation and execution result all cached query results that contain the type
User with the id 1 will be invalidated.
This behavior can be disabled by setting the invalidateViaMutation option to false.
Manual Invalidation
You can invalidate a type or specific instances of a type using the cache invalidation API.
In order to use the API, you need to manually instantiate the cache an pass it to the
useResponseCache plugin.
Then in your business logic you can call the invalidate method on the cache instance.
Invalidate all GraphQL query results that reference a specific type:
Invalidate all GraphQL query results that reference a specific entity of a type:
Invalidate all GraphQL query results multiple entities in a single call.
External Cache
By default, the response cache stores all the cached query results in memory.
If you want a cache that is shared between multiple server instances you can use the Redis cache implementation, which is available as a separate package.
HTTP Caching via ETag and If-None-Match headers
Response Caching plugin sends ETag headers to the client, and respects If-None-Match headers in
the HTTP request.
If the client sends an If-None-Match header with the same value as the ETag header, the server
will respond with a 304 Not Modified status code without any content, which allows you to reduce
the server load.
Most of the browsers and some HTTP clients support this behavior, so you can use it to improve the performance of your frontend application.
Learn more about ETag and If-None-Match headers.
Example with curl
First we send a request to the GraphQL server, and we can see that the response contains the headers
Then the server will respond a data something the following with the ETag and Last-Modified
headers:
ETagis the key that is used to identify the cached response.Last-Modifiedis used to determine if the cached response is still valid.
In the next calls, we can use the ETag header as the If-None-Match header together with
Last-Modified header as If-Modified-Since to check if the cached response is still valid.
Then the server will return 304: Not Modified status code with no content.