GraphQL caching

Magento can cache pages rendered from the results of certain GraphQL queries with full-page caching. Full-page caching improves response time and reduces the load on the server. Without caching, each page might need to run blocks of code and retrieve large amounts of information from the database. Only queries submitted with an HTTP GET operation can be cached. POST queries cannot be cached.

Cached queries

The definitions for some queries include cache tags. Full page caching uses these tags to keep track of cached content. They also allow public content to be invalidated. Private content invalidation is handled on the client side.

Magento caches the following queries:

  • category (deprecated)
  • categoryList
  • cmsBlocks
  • cmsPage
  • products
  • urlResolver

Magento explicitly disallows caching the following queries.

  • cart
  • country
  • countries
  • currency
  • customAttributeMetadata
  • customer
  • customerDownloadableProducts
  • customerOrders
  • customerPaymentTokens
  • storeConfig
  • wishlist

Define the GraphQL schema for a module describes the syntax of a valid query.

Caching with Varnish

We recommend setting up Varnish as a reverse proxy to serve the full page cache in a production environment. See Configure and use Varnish for more information.

As of Magento 2.3.2, Magento supports GraphQL caching with Varnish. If you have upgraded from a previous version, you can enable GraphQL caching by generating a new template file, or by editing the default.vcl file on your system to match the current default template for your version of Varnish.

If you choose to edit an existing default.vcl file, update the vcl_hash subroutine to check whether the request URL contains graphql, as follows:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
sub vcl_hash {
    if (req.http.cookie ~ "X-Magento-Vary=") {
        hash_data(regsub(req.http.cookie, "^.*?X-Magento-Vary=([^;]+);*.*$", "\1"));
    }

    # For multi site configurations to not cache each other's content
    if (req.http.host) {
        hash_data(req.http.host);
    } else {
        hash_data(server.ip);
    }

    if (req.url ~ "/graphql") {
        call process_graphql_headers;
    }

    # To make sure http users don't see ssl warning
    if (req.http./*  */) {
        hash_data(req.http./*  */);
    }
}

Then add the process_graphql_headers subroutine:

1
2
3
4
5
6
7
8
sub process_graphql_headers {
    if (req.http.Store) {
        hash_data(req.http.Store);
    }
    if (req.http.Content-Currency) {
        hash_data(req.http.Content-Currency);
    }
}

Query results should not be cached for logged in customers, because it cannot be guaranteed that these results are applicable to all customers. For example, you can create multiple customer groups and set up different product prices for each group. Caching results like these might cause customers to see the prices of another customer group.

To prevent customers from seeing the incorrect data from cached results, add the following to your .vcl file in the vcl_recv subroutine before the return (hash):

1
2
3
4
# Authenticated GraphQL requests should not be cached by default
if (req.url ~ "/graphql" && req.http.Authorization ~ "^Bearer") {
    return (pass);
}

This statement prevents any query with an authorization token from being cached.

Configure Varnish and your web server further describes how to configure the default.vcl file.

Caching with Fastly

To cache GraphQL query results on Magento Commerce Cloud, the Cloud project must be running Fastly CDN module for Magento 2 version 1.2.118 or later.

To enable GraphQL caching on Fastly:

  1. Upgrade the Fastly CDN Module for Magento 2.x to version 1.2.118 or later.
  2. Upload the updated VCL code to the Fastly servers.

Set up Fastly describes how to perform both of these tasks.

X-Magento-Vary

The X-Magento-Vary cache cookie is not supported for GraphQL. The Store and Content-Currency headers, along with the content language (which is deduced) determine the context.

Response headers

In developer mode, Magento returns several headers that could be useful for debugging caching problems. These headers are not specific to GraphQL.

Header Description
X-Magento=Cache-Debug HIT (the page was loaded from cache) or MISS (the page was not loaded from cache.
X-Magento-Tags A list of cache tags that correspond to the catalog, category, or CMS items returned in the query. Magento caches these items.

Cache invalidation

Magento invalidates the cache when any of the following events occur:

  • When a change occurs to a specific entity or entities in aggregate. An increase in a product’s price is a direct and obvious change. Applying a new tax class tax to products changes a set of products in aggregate.
  • When system configuration changes
  • When an administrator flushes or disables the cache from the Admin or with the bin/magento cache command