Response Caching

GraphQL Response Caching

GraphQL Response Caching is a feature that allows you to cache the response of a GraphQL query. This is useful when you want to reduce the number of requests to your sources. For example, if you have a GraphQL query that fetches a list of products, you can cache the response of this query so that the next time the same query is made, the response is fetched from the cache instead of making a request to the underlying sources.

GraphQL Mesh’s Response Cache Plugin uses Envelop’s Response Caching under the hood.

You can learn more on Envelop’s docs.


The defined cache storage will be used for this plugin. By default, GraphQL Mesh uses Localforage as a cache storage. For example, you need to follow this section to configure Redis as your cache storage. You can find other options under the same category.

Getting Started

npm i @graphql-mesh/plugin-response-cache

Then add the plugin to your configuration;

# ...
  - responseCache: {}

The caching behavior can be fully customized. A TTL can be provided global or more granular per type or schema coordinate.

# ...
  - responseCache:
      # cache operations for 1 hour
      ttl: 60 * 60 * 1000,
        # cache operation containing Stock object type for 500ms
        - coordinate: Stock
          ttl: 500
        # cache operation containing Query.rocketCoordinates selection for 100ms
        - coordinate: Query.rocketCoordinates
          ttl: 100
        # never cache responses that include a RefreshToken object type
        - RefreshToken

If you need to cache based on the user;

# ...
  - responseCache:
      if: 'context.headers.authorization != null'
      session: '{context.headers.authorization}'

If you don’t want to invalidate automatically based on mutations;

# ...
  - responseCache:
      invalidateViaMutation: false

This plugin also uses ETag and other cache headers to benefit from HTTP caching. See more

Config API Reference

  • ttl (type: Float) - Maximum age in ms. Defaults to Infinity. Set it to 0 for disabling the global TTL.
  • ttlPerCoordinate (type: Array of Object) - Overwrite the ttl for query operations whose selection contains a specific schema coordinate (e.g. Query.users). Useful if the selection of a specific field should reduce the TTL of the query operation.:
    • coordinate (type: String, required)
    • ttl (type: Float, required)
  • ignoredTypes (type: Array of String) - Skip caching of following the types.
  • idFields (type: Array of String) - List of fields that are used to identify the entity.
  • invalidateViaMutation (type: Boolean) - Whether the mutation execution result should be used for invalidating resources. Defaults to true
  • includeExtensionMetadata (type: Boolean) - Include extension values that provide useful information, such as whether the cache was hit or which resources a mutation invalidated.
  • sessionId (type: String) - Allows to cache responses based on the resolved session id. Return a unique value for each session. Creates a global session by default. Example;
sessionId: "{context.headers.userId}"
  • if (type: String) - Specify whether the cache should be used based on the context.
if: "context.headers.userId != null"
  • cacheKey (type: String) - Customize the behavior how the response cache key is computed from the documentString, variableValues, contextValue and sessionId. If the given string is interpolated as empty, default behavior is used. Example;
# Cache by specific value
cacheKey: "{variableValues.userId}"
# Cache by documentString
cacheKey: "{documentString}"
# Cache by operationName
cacheKey: "{operationName}"
# Cache by some header value
cacheKey: "{contextValue.headers.authorization}"
# Or combine two of each
cacheKey: "{contextValue.headers.authorization}-{operationName}"
  • shouldCacheResult (type: String) - Checks if the result should be cached.
shouldCacheResult: "result.errors.length > 0"

CodeSandBox Example

You can check the “Location Weather” example that uses OpenAPI handler with cache transform;