{"id":31697,"date":"2024-08-27T11:24:10","date_gmt":"2024-08-27T16:24:10","guid":{"rendered":"https:\/\/wpengine.com\/builders\/?p=31697"},"modified":"2024-09-10T09:13:43","modified_gmt":"2024-09-10T14:13:43","slug":"how-to-customize-wpgraphql-cache-keys","status":"publish","type":"post","link":"https:\/\/wpengine.com\/builders\/how-to-customize-wpgraphql-cache-keys\/","title":{"rendered":"How to Customize WPGraphQL Cache Keys \ud83d\udcbe\ud83d\udd11"},"content":{"rendered":"\n<p>Caching is important in optimizing performance for headless WordPress setups. The WPGraphQL Smart Cache plugin helps manage caching for GraphQL queries, ensuring faster response times. In this guide, we&#8217;ll walk you through setting up your WordPress environment, installing the necessary plugins, and customizing GraphQL cache keys to better suit your specific needs.<\/p>\n\n\n\n<div class=\"wp-block-group has-polar-background-color has-background is-layout-flow wp-container-core-group-is-layout-7a03825d wp-block-group-is-layout-flow\" style=\"padding-top:var(--wp--preset--spacing--30);padding-right:var(--wp--preset--spacing--40);padding-bottom:var(--wp--preset--spacing--30);padding-left:var(--wp--preset--spacing--40)\">\n<p class=\"has-large-font-size\"><strong>Table of Contents<\/strong><\/p>\n\n\n\n<ul id=\"Prerequisites\" class=\"wp-block-list\">\n<li><a href=\"#prerequisites\">Prerequisites<\/a><\/li>\n\n\n\n<li><a href=\"#understanding-default-smart-cache-behavior\">Understanding Default WPGraphQL Smart Cache Behavior<\/a><\/li>\n\n\n\n<li><a href=\"#understanding-cache-invalidation-wpgraphql-smart-cache\">Understanding Cache Invalidation with WPGraphQL Smart Cache<\/a><\/li>\n\n\n\n<li><a href=\"#How Cache Invalidation and Cache Tags Work Together\">How Cache Invalidation and Cache Tags Work Together<\/a><\/li>\n\n\n\n<li><a href=\"#why-you-need-to-customize-cache-keys\">Why Would You Need to Customize WPGraphQL Cache Keys?<\/a><\/li>\n\n\n\n<li><a href=\"#just-a-note\">Just A Note<\/a><\/li>\n\n\n\n<li><a href=\"#the-problem\">The Problem<\/a><\/li>\n\n\n\n<li><a href=\"#customizing-cache-keys\">Customizing Cache Keys<\/a><\/li>\n\n\n\n<li><a href=\"#headlesswp-user-portal\">Conclusion<\/a><\/li>\n<\/ul>\n<\/div>\n\n\n\n<h2 class=\"wp-block-heading\">Prerequisites<\/h2>\n\n\n\n<p>Before reading this article, you should have the following prerequisites checked off:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>A WordPress installation that supports <a href=\"https:\/\/wordpress.org\/plugins\/wpgraphql-smart-cache\/\">WPGraphQL Smart Cache<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/www.wpgraphql.com\/\">WPGraphQL<\/a>&nbsp;<\/li>\n\n\n\n<li>WPGraphQL Smart Cache<\/li>\n\n\n\n<li>A basic knowledge of developer tools in your browser<\/li>\n<\/ul>\n\n\n\n<p>If you\u2019re looking for a headless platform to develop on, you can get started with a WP Engine Headless WordPress sandbox site for free:<\/p>\n\n\n\n<div class=\"wp-block-group has-base-color has-heliotrope-background-color has-text-color has-background has-link-color wp-elements-60580c77f35127ab4c58efd3ae854863 has-global-padding is-layout-constrained wp-container-core-group-is-layout-9b866ece wp-block-group-is-layout-constrained\" style=\"border-radius:12px;margin-bottom:var(--wp--preset--spacing--30);padding-top:var(--wp--preset--spacing--30);padding-right:var(--wp--preset--spacing--30);padding-bottom:var(--wp--preset--spacing--30);padding-left:var(--wp--preset--spacing--30)\">\n<div class=\"wp-block-group alignwide is-content-justification-left is-layout-flex wp-container-core-group-is-layout-4bb02320 wp-block-group-is-layout-flex\" style=\"padding-top:0;padding-right:0;padding-bottom:0;padding-left:0\">\n<p style=\"font-size:26px;font-style:normal;font-weight:700;letter-spacing:-1px;line-height:1\">Headless<br>Platform<\/p>\n\n\n\n<p class=\"has-small-font-size wp-container-content-9cfa9a5a\" style=\"line-height:1.5\">The all-in-one platform for <br>radically fast headless sites.<\/p>\n\n\n\n<div class=\"wp-block-buttons is-content-justification-right is-nowrap is-layout-flex wp-container-core-buttons-is-layout-b315634e wp-block-buttons-is-layout-flex\">\n<div class=\"wp-block-button is-style-outline-base\"><a class=\"wp-block-button__link wp-element-button\" href=\"https:\/\/wpeng.in\/headless-platform\/\" style=\"border-radius:99px;padding-top:10px;padding-right:24px;padding-bottom:10px;padding-left:24px\" target=\"_blank\" rel=\"noreferrer noopener\">Try for free \u2192<\/a><\/div>\n<\/div>\n<\/div>\n<\/div>\n\n\n\n<div class=\"wp-block-group has-base-color has-text-color has-background has-link-color wp-elements-688844c5591b0d750f2228c71fe3f5ec has-global-padding is-layout-constrained wp-container-core-group-is-layout-c825ac28 wp-block-group-is-layout-constrained\" style=\"border-radius:12px;background-color:#180038;margin-bottom:var(--wp--preset--spacing--30);padding-top:var(--wp--preset--spacing--30);padding-right:var(--wp--preset--spacing--30);padding-bottom:var(--wp--preset--spacing--30);padding-left:var(--wp--preset--spacing--30)\">\n<div class=\"wp-block-group alignwide is-content-justification-left is-layout-flex wp-container-core-group-is-layout-682063c7 wp-block-group-is-layout-flex\" style=\"padding-top:0;padding-right:0;padding-bottom:0;padding-left:0\">\n<div class=\"wp-block-group is-nowrap is-layout-flex wp-container-core-group-is-layout-e4830150 wp-block-group-is-layout-flex\">\n<div class=\"wp-block-outermost-icon-block\"><div class=\"icon-container\" style=\"width:38px\"><svg fill=\"none\" viewBox=\"0 0 38 30\" aria-label=\"Frost logo\"><path fill=\"currentColor\" fill-rule=\"evenodd\" d=\"M18.149.498c-.043.01-.16.025-.259.033-.406.03-.933.112-1.53.238-.205.043-.769.198-.98.269-.114.039-.574.207-.618.226l-.292.124c-.3.128-.74.346-1.01.502a4.92 4.92 0 0 1-.206.115 10.57 10.57 0 0 0-4.878 6.728c-.018.106-.035.118-.237.165-.17.039-.23.055-.54.147C3.36 10.302.453 13.9.037 18.401c-.045.49-.05 8.792-.006 9.065.18 1.094.97 1.87 2.052 2.012.375.049 4.136.05 4.527.002 1.185-.148 2.032-1.046 2.102-2.228.055-.925.614-1.62 1.403-1.745.29-.046.37-.05.528-.022.905.158 1.437.76 1.5 1.7.083 1.249.888 2.135 2.084 2.294.363.048 4.162.048 4.518 0 .633-.086 1.262-.421 1.616-.862l.124-.154c.13-.156.29-.575.341-.885.046-.277.047-8.617.002-8.907-.183-1.17-1.208-1.979-2.505-1.979-.386 0-1.057-.13-1.593-.306a5.82 5.82 0 0 1-3.868-4.496c-.16-.907-.112-1.586.187-2.655.417-1.494 1.717-2.941 3.22-3.585l.158-.068c.28-.121.809-.268 1.214-.336a5.03 5.03 0 0 1 1.98.042c2.288.53 3.911 2.078 4.476 4.272.198.768.189.427.19 7.436.002 3.432.012 6.28.023 6.399.304 3.24 2.565 5.63 5.713 6.037.829.107 1.116.107 1.8-.001 2.037-.322 3.807-1.829 4.698-4.001l.046-.112c.148-.36.347-1.107.407-1.53.119-.823.073-1.372-.15-1.817-.255-.508-.802-.924-1.493-1.137-.253-.078-.998-.08-1.2-.005-.026.01-.11.037-.183.06-.666.202-1.24.854-1.493 1.696-.03.101-.093.523-.093.63 0 .044-.02.162-.046.26-.44 1.724-2.917 1.715-3.316-.013-.03-.128-.034-.905-.034-6.275 0-6.296-.005-6.684-.089-7.276a11.333 11.333 0 0 0-.114-.742c-.012-.05-.042-.186-.066-.304-.734-3.596-3.431-6.625-6.951-7.805a9.125 9.125 0 0 0-.855-.246 7.503 7.503 0 0 0-.888-.179 18.617 18.617 0 0 0-.877-.117c-.28-.033-.874-.046-.977-.02Zm-.047 8.132c-1.224.212-1.998 1.382-1.8 2.72.027.186.034.213.115.462.554 1.717 3.03 1.998 3.992.452.055-.088.1-.165.1-.172 0-.006.025-.064.056-.128.131-.27.214-.68.214-1.052 0-1.52-1.194-2.539-2.677-2.282Zm-9.55 5.116c.577 2.153 2.094 4.3 3.988 5.648.78.554 1.328.849 2.38 1.28.077.031.556.195.675.23l.247.07.236.069.101.03.006 1.66c.006 1.695.002 1.779-.078 1.615-.772-1.58-2.366-2.836-4.134-3.256-.626-.149-.883-.178-1.552-.178-2.132.001-4.114 1.027-5.234 2.711-.17.254-.36.57-.412.686-.101.22-.1.256-.1-2.611 0-3 .005-3.148.129-3.748a5.873 5.873 0 0 1 1.94-3.294 5.92 5.92 0 0 1 1.518-.927c.222-.091.262-.09.29.015Z\" clip-rule=\"evenodd\"><\/path><\/svg><\/div><\/div>\n\n\n\n<p class=\"has-large-font-size\" style=\"font-style:normal;font-weight:800;letter-spacing:-1px\">WPGraphQL<\/p>\n<\/div>\n\n\n\n<p class=\"has-small-font-size wp-container-content-c86e52ed\" style=\"line-height:1.5\">An extendable GraphQL <br>schema &amp; API for WordPress.<\/p>\n\n\n\n<div class=\"wp-block-buttons is-horizontal is-content-justification-center is-nowrap is-layout-flex wp-container-core-buttons-is-layout-3bdbf2e2 wp-block-buttons-is-layout-flex\">\n<div class=\"wp-block-button is-style-outline-base\"><a class=\"wp-block-button__link wp-element-button\" href=\"https:\/\/wpeng.in\/wpgraphql-builders\/\" style=\"border-radius:99px;padding-top:10px;padding-right:24px;padding-bottom:10px;padding-left:24px\" target=\"_blank\" rel=\"noreferrer noopener\">Download<\/a><\/div>\n<\/div>\n<\/div>\n<\/div>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"understanding-default-smart-cache-behavior\">Understanding Default WPGraphQL Smart Cache Behavior<\/h2>\n\n\n\n<p>WPGraphQL Smart Cache automatically tags cached responses with keys derived from the GraphQL queries. These keys are linked to specific WordPress data (e.g., posts, pages, taxonomies). When relevant data is updated, the associated cache is invalidated.&nbsp;<\/p>\n\n\n\n<p>For example, a query that retrieves posts with specific categories and tags will generate cache keys like <code>list:post<\/code>, <code>list:category<\/code>, and <code>list:tag<\/code>. If any of these categories or tags are updated, the entire cache is invalidated, ensuring the data stays current.&nbsp;&nbsp;<\/p>\n\n\n\n<p>In addition to the <code>list:$type_name<\/code> keys, individual node IDs are also included.&nbsp;<\/p>\n\n\n\n<p>These individual IDs are used to purge cache when updates or deletes happen.<\/p>\n\n\n\n<p>The <code>list:$type_name<\/code> is used to purge when a new thing is published.&nbsp; For example <code>list:post<\/code> will be purged when a new post is published, but <code>purge( \"post:1\" )<\/code> would be purged when post 1 is updated or deleted.&nbsp;&nbsp;&nbsp;<\/p>\n\n\n\n<p>Let\u2019s see this in action.&nbsp; Navigate to your WP admin, then open your <a href=\"https:\/\/github.com\/wp-graphql\/wpgraphql-ide\">WPGraphQL IDE<\/a>. Copy and paste this query:<\/p>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs shcb-code-table shcb-line-numbers\"><span class='shcb-loc'><span>query GetPosts {\n<\/span><\/span><span class='shcb-loc'><span>  posts {\n<\/span><\/span><span class='shcb-loc'><span>    nodes {\n<\/span><\/span><span class='shcb-loc'><span>      title\n<\/span><\/span><span class='shcb-loc'><span>      uri\n<\/span><\/span><span class='shcb-loc'><span>    }\n<\/span><\/span><span class='shcb-loc'><span>  }\n<\/span><\/span><span class='shcb-loc'><span>}\n<\/span><\/span><span class='shcb-loc'><span>\n<\/span><\/span><\/code><\/span><\/pre>\n\n\n<p>When you press play in your IDE, this will make a query to your site\u2019s WPGraphQL endpoint.&nbsp; <\/p>\n\n\n\n<p>Then WPGraphQL will return headers that caching clients can use to tag the cached document. Next, Open your dev tools.&nbsp; In this case, I am using <a href=\"https:\/\/www.google.com\/chrome\/\">Google Chrome<\/a>.&nbsp; When I open up the dev tools and inspect the response headers, you should see this:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"486\" src=\"https:\/\/wpengine.com\/builders\/wp-content\/uploads\/2024\/08\/Screenshot-2024-08-27-at-8.58.03\u202fAM-1024x486.png\" alt=\"\" class=\"wp-image-31699\" srcset=\"https:\/\/wpengine.com\/builders\/wp-content\/uploads\/2024\/08\/Screenshot-2024-08-27-at-8.58.03\u202fAM-1024x486.png 1024w, https:\/\/wpengine.com\/builders\/wp-content\/uploads\/2024\/08\/Screenshot-2024-08-27-at-8.58.03\u202fAM-300x142.png 300w, https:\/\/wpengine.com\/builders\/wp-content\/uploads\/2024\/08\/Screenshot-2024-08-27-at-8.58.03\u202fAM-768x364.png 768w, https:\/\/wpengine.com\/builders\/wp-content\/uploads\/2024\/08\/Screenshot-2024-08-27-at-8.58.03\u202fAM-1536x729.png 1536w, https:\/\/wpengine.com\/builders\/wp-content\/uploads\/2024\/08\/Screenshot-2024-08-27-at-8.58.03\u202fAM-2048x972.png 2048w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>Here, we see the X-GraphQL-Keys header with a list of keys. If this query were made via a GET request to a site hosted on a host that supports it, the response would be cached and \u201ctagged\u201d with these keys.<\/p>\n\n\n\n<p>For this particular query, we see the following keys:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Hash of the Query<\/strong>: This is a unique identifier which is in this example <\/li>\n<\/ul>\n\n\n\n<p><code>4382426a7bebd62479da59a06d90ceb12e02967d342afb7518632e26b95acc6f<\/code> for the specific query made. It ensures that the exact same query returns the same cached response unless invalidated.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Operation Type (<code>graphql:Query<\/code>)<\/strong>: Indicates that the operation is a GraphQL query, as opposed to a mutation or subscription<\/li>\n<\/ul>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Operation Name (<\/strong><code><strong>operation:GetPosts<\/strong><\/code><strong>)<\/strong>: Identifies the specifically named query, in this case, <code>GetPosts<\/code>, which helps in targeting this operation for caching or invalidation.<\/li>\n<\/ul>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>List Key<\/strong> <strong>(<\/strong><code>list:post<\/code><strong>)<\/strong>: This key identifies that the query is fetching a list of posts. Any changes to the list of posts would trigger cache invalidation.<\/li>\n<\/ul>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Node ID (<\/strong><code>cG9zdDox<\/code><strong>)<\/strong>: This represents the specific node (e.g., a post) that was resolved in the query. Changes to this node will invalidate the cache for this query.<\/li>\n<\/ul>\n\n\n\n<p>If a purge event for one of those tags is triggered, the document will be tagged with these keys and purged (deleted) from the cache.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"understanding-cache-invalidation-wpgraphql-smart-cache\">Understanding Cache Invalidation with WPGraphQL Smart Cache<\/h2>\n\n\n\n<p>WPGraphQL Smart Cache optimizes caching by sending the keys in the headers, but the caching client (e.g., Varnish or Litespeed) needs to use those keys to tag the cache. WPGraphQL Smart Cache itself does not tag the cached document; it provides the caching client info (the keys) to tag the cached document with. A supported host like WP engine works with WPGraphQL Smart Cache out of the box.<\/p>\n\n\n\n<p>Let\u2019s discuss how invalidation works:<\/p>\n\n\n\n<p>WPGraphQL Smart Cache listens to various events in WordPress, such as publishing, updating, or deleting content, and triggers cache invalidation (or &#8220;purge&#8221;) based on these events.<\/p>\n\n\n\n<p>Detailed Key Breakdown:<\/p>\n\n\n\n<p>Publish Events <code>(purge('list:$type_name'))<\/code>: When a new post or content type is published, the cache for the entire list associated with that content type (e.g., all posts) is purged. This ensures that any queries fetching this list will be up-to-date.<\/p>\n\n\n\n<p>&nbsp;&nbsp;Update Events <code>(purge('$nodeId'))<\/code>: When an existing post or content type is updated, the cache for that specific node (e.g., a single post) is purged. This allows the updated content to be fetched without affecting the entire list.<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;Delete Events <code>(purge('$nodeId'))<\/code>: Similarly, when a post or content type is deleted, the cache for that specific node is purged, ensuring that the deleted content is no longer served from the cache.<\/p>\n\n\n\n<p>Why This Matters:<\/p>\n\n\n\n<p>These targeted cache invalidations help maintain the balance between performance and data freshness. By only purging the cache when necessary and only for the relevant data, WPGraphQL Smart Cache ensures that users receive up-to-date content without unnecessary cache purges, which can negatively impact performance.<\/p>\n\n\n\n<p>This invalidation strategy is crucial for optimizing the performance of headless WordPress setups using WPGraphQL, especially in dynamic environments where content changes frequently.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"How-Cache-Invalidation-and-Cache-Tags-Work-Together\">How Cache Invalidation and Cache Tags Work Together<\/h2>\n\n\n\n<p>Now that we&#8217;ve explored how cached documents are tagged and how cache invalidation works in WPGraphQL Smart Cache, let&#8217;s see how these concepts interact.<\/p>\n\n\n\n<p>When a GraphQL query is executed, specific cache keys (tags) are associated with the cached response. These tags correspond to the data queried, such as posts, categories, or specific node IDs. The cache invalidation strategy then ensures that when relevant data changes occur in WordPress, the associated cached documents are purged based on these tags.<\/p>\n\n\n\n<p>Example: Invalidation Scenarios for a GetPosts Query<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>Publishing a New Post <code>(purge('list:post'))<\/code><\/strong>:\n<ul class=\"wp-block-list\">\n<li>When a new post is published, the entire list of posts in the cache (tagged with list:post) is invalidated. This ensures that the new post will appear in any subsequent queries that fetch this list.<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>Updating or Deleting a Specific Node <code>(purge('$nodeId'))<\/code><\/strong>:\n<ul class=\"wp-block-list\">\n<li>If the &#8220;Hello World&#8221; post (with the ID cG9zdDox) is updated or deleted, the cache for that specific node is purged. This allows the updated or deleted content to be accurately reflected in any future queries.<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>Manually Purging Cache <code>(purge('graphql:Query'))<\/code><\/strong>:\n<ul class=\"wp-block-list\">\n<li>Clicking &#8220;Purge Cache&#8221; in <strong>GraphQL &gt; Settings &gt; Cache<\/strong> page triggers a manual cache purge for all queries. This can be useful when you want to ensure that all cached data is refreshed, regardless of specific events.<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>Operation Name or Query Hash-Based Purge<\/strong>:\n<ul class=\"wp-block-list\">\n<li>Custom purge events can be manually triggered based on the operation name (e.g., <code>GetPosts<\/code>) or the hash of the query. This level of control allows you to finely tune when and how caches are invalidated.<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n\n\n\n<p>These strategies work together to ensure that the cache is only invalidated when necessary, providing up-to-date data without unnecessary performance overhead. For instance, when the <em>&#8220;Hello World&#8221;<\/em> post is updated, it&#8217;s reasonable to expect that the cache for the GetPosts query should be purged so that any queries return the most current data. This fine-grained control over cache invalidation ensures that your headless WordPress site remains performant while delivering fresh content.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"why-you-need-to-customize-cache-keys\">Why Would You Need to Customize WPGraphQL Cache Keys?<\/h2>\n\n\n\n<p>In some scenarios, the default caching behavior might be too broad, leading to frequent cache invalidations.&nbsp; This is especially true for more complex queries.&nbsp;<\/p>\n\n\n\n<p>For instance, if your query includes categories and tags, any update to these taxonomies will invalidate the cache, even if those changes don&#8217;t affect the specific posts you&#8217;re querying. Customizing cache keys allows you to fine-tune this behavior, ensuring that only relevant updates trigger cache invalidation, thereby improving performance.<\/p>\n\n\n\n<p>For example, consider the following query:<\/p>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs shcb-code-table shcb-line-numbers\"><span class='shcb-loc'><span>{\n<\/span><\/span><span class='shcb-loc'><span>  posts {\n<\/span><\/span><span class='shcb-loc'><span>    nodes {\n<\/span><\/span><span class='shcb-loc'><span>      id\n<\/span><\/span><span class='shcb-loc'><span>      title\n<\/span><\/span><span class='shcb-loc'><span>      tags {\n<\/span><\/span><span class='shcb-loc'><span>        nodes {\n<\/span><\/span><span class='shcb-loc'><span>          id\n<\/span><\/span><span class='shcb-loc'><span>          name\n<\/span><\/span><span class='shcb-loc'><span>        }\n<\/span><\/span><span class='shcb-loc'><span>      }\n<\/span><\/span><span class='shcb-loc'><span>    }\n<\/span><\/span><span class='shcb-loc'><span>  }\n<\/span><\/span><span class='shcb-loc'><span>  categories {\n<\/span><\/span><span class='shcb-loc'><span>    nodes {\n<\/span><\/span><span class='shcb-loc'><span>      id\n<\/span><\/span><span class='shcb-loc'><span>      name\n<\/span><\/span><span class='shcb-loc'><span>    }\n<\/span><\/span><span class='shcb-loc'><span>  }\n<\/span><\/span><span class='shcb-loc'><span>  tags {\n<\/span><\/span><span class='shcb-loc'><span>    nodes {\n<\/span><\/span><span class='shcb-loc'><span>      id\n<\/span><\/span><span class='shcb-loc'><span>      name\n<\/span><\/span><span class='shcb-loc'><span>    }\n<\/span><\/span><span class='shcb-loc'><span>  }\n<\/span><\/span><span class='shcb-loc'><span>}\n<\/span><\/span><\/code><\/span><\/pre>\n\n\n<p>This query retrieves a list of posts, along with all categories and tags. When this query is executed, the response includes the posts, categories, and tags that match the query as shown here:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"467\" src=\"https:\/\/wpengine.com\/builders\/wp-content\/uploads\/2024\/08\/Screenshot-2024-08-27-at-10.35.14\u202fAM-1024x467.png\" alt=\"\" class=\"wp-image-31700\" srcset=\"https:\/\/wpengine.com\/builders\/wp-content\/uploads\/2024\/08\/Screenshot-2024-08-27-at-10.35.14\u202fAM-1024x467.png 1024w, https:\/\/wpengine.com\/builders\/wp-content\/uploads\/2024\/08\/Screenshot-2024-08-27-at-10.35.14\u202fAM-300x137.png 300w, https:\/\/wpengine.com\/builders\/wp-content\/uploads\/2024\/08\/Screenshot-2024-08-27-at-10.35.14\u202fAM-768x350.png 768w, https:\/\/wpengine.com\/builders\/wp-content\/uploads\/2024\/08\/Screenshot-2024-08-27-at-10.35.14\u202fAM-1536x701.png 1536w, https:\/\/wpengine.com\/builders\/wp-content\/uploads\/2024\/08\/Screenshot-2024-08-27-at-10.35.14\u202fAM-2048x934.png 2048w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>The X-GraphQL-Keys header shows that the cached document is tagged with <code>list:post<\/code>, <code>list:category<\/code>, and <code>list:tag<\/code>. This tagging means that the cache will be invalidated whenever there\u2019s a change in any of these entities\u2014whether it&#8217;s a new post, category, or tag.<\/p>\n\n\n\n<p>While this behavior ensures that your cache is up-to-date, it can lead to excessive cache invalidation. For instance, if a new tag is created and assigned to a post not included in this query, it will still trigger a purge(<code>'list:tag'<\/code>), invalidating the cache for this query. <\/p>\n\n\n\n<p>This means the cache could be cleared more often than you want for your specific use case, which could negatively impact performance.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"just-a-note\">Just A Note<\/h3>\n\n\n\n<p>Just a note, consider this query from <a href=\"https:\/\/www.wpgraphql.com\/2023\/05\/24\/customizing-graphql-cache-keys\">the original article<\/a> on this subject:<\/p>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs shcb-code-table shcb-line-numbers\"><span class='shcb-loc'><span>query GetPostsWithCategoriesAndTags {\n<\/span><\/span><span class='shcb-loc'><span>  posts {\n<\/span><\/span><span class='shcb-loc'><span>    nodes {\n<\/span><\/span><span class='shcb-loc'><span>      id\n<\/span><\/span><span class='shcb-loc'><span>      title\n<\/span><\/span><span class='shcb-loc'><span>      categories {\n<\/span><\/span><span class='shcb-loc'><span>        nodes {\n<\/span><\/span><span class='shcb-loc'><span>          id\n<\/span><\/span><span class='shcb-loc'><span>          name\n<\/span><\/span><span class='shcb-loc'><span>        }\n<\/span><\/span><span class='shcb-loc'><span>      }\n<\/span><\/span><span class='shcb-loc'><span>      tags {\n<\/span><\/span><span class='shcb-loc'><span>        nodes {\n<\/span><\/span><span class='shcb-loc'><span>          id\n<\/span><\/span><span class='shcb-loc'><span>          name\n<\/span><\/span><span class='shcb-loc'><span>        }\n<\/span><\/span><span class='shcb-loc'><span>      }\n<\/span><\/span><span class='shcb-loc'><span>    }\n<\/span><\/span><span class='shcb-loc'><span>  }\n<\/span><\/span><span class='shcb-loc'><span>}\n<\/span><\/span><span class='shcb-loc'><span>\n<\/span><\/span><\/code><\/span><\/pre>\n\n\n<p>The WPGraphQL team changed things to only track <code>list: types<\/code> from the root.&nbsp; So, if you run this query, your list of categories won\u2019t be tracked because it is not at the root.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"the-problem\">The Problem<\/h3>\n\n\n\n<p>The problem is that the <code>list:category<\/code> and <code>list:tag<\/code> keys could cause this document to be purged more frequently than you might like. WPGraphQL tracks precisely, but it doesn&#8217;t know your specific intention and what you care about.<\/p>\n\n\n\n<p>For example, you might simply not care if this particular query is &#8220;fresh&#8221; when terms change. OR you might ONLY care for this query to be fresh when terms change.&nbsp;<\/p>\n\n\n\n<p>WPGraphQL doesn&#8217;t know the intent of the query, only what the query is.<\/p>\n\n\n\n<p>Fortunately, you can customize the cache keys to better suit your specific needs, reducing unnecessary cache invalidations and improving performance.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"customizing-cache-keys\">Customizing Cache Keys<\/h2>\n\n\n\n<p>By customizing the cache keys, you can ensure that the cache is only invalidated when changes you believe are relevant to your use case occur. This involves fine-tuning the tags associated with your queries, allowing you to maintain optimal performance without sacrificing data accuracy.<\/p>\n\n\n\n<p>Let\u2019s do this by navigating to our WP admin and modifying the <code>functions.php<\/code> file.&nbsp; Go to <strong>Appearance&gt; Theme File Editor<\/strong>.&nbsp; Select the <code>functions.php<\/code> file from your active theme.<\/p>\n\n\n\n<p>Insert this code snippet at the bottom of your <code>functions.php<\/code> file to customize the cache keys for a specific GraphQL operation.\u00a0 In this case, let&#8217;s add an operator name to the query we used in the section before.\u00a0 We are calling our operation <code>GetPostWithCategoriesAndTags<\/code>:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-1\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php shcb-code-table shcb-line-numbers\"><span class='shcb-loc'><span>add_filter( <span class=\"hljs-string\">'graphql_query_analyzer_graphql_keys'<\/span>, <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span><span class=\"hljs-params\">( $graphql_keys, $return_keys )<\/span> <\/span>{\n<\/span><\/span><span class='shcb-loc'><span>    $keys_array = explode( <span class=\"hljs-string\">' '<\/span>, $return_keys );\n<\/span><\/span><span class='shcb-loc'><span>    <span class=\"hljs-keyword\">if<\/span> ( ! in_array( <span class=\"hljs-string\">'operation:GetPostsWithCategoriesAndTags'<\/span>, $keys_array, <span class=\"hljs-keyword\">true<\/span> ) ) {\n<\/span><\/span><span class='shcb-loc'><span>        <span class=\"hljs-keyword\">return<\/span> $graphql_keys;\n<\/span><\/span><span class='shcb-loc'><span>    }\n<\/span><\/span><span class='shcb-loc'><span>    $keys_array = array_diff($keys_array, &#91;<span class=\"hljs-string\">'list:tag'<\/span>, <span class=\"hljs-string\">'list:category'<\/span>]);\n<\/span><\/span><span class='shcb-loc'><span>    $graphql_keys&#91;<span class=\"hljs-string\">'keys'<\/span>] = implode( <span class=\"hljs-string\">' '<\/span>, $keys_array );\n<\/span><\/span><span class='shcb-loc'><span>    <span class=\"hljs-keyword\">return<\/span> $graphql_keys;\n<\/span><\/span><span class='shcb-loc'><span>}, <span class=\"hljs-number\">10<\/span>, <span class=\"hljs-number\">5<\/span> );\n<\/span><\/span><span class='shcb-loc'><span>\n<\/span><\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-1\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>You should have something that looks like this:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large is-resized\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"547\" src=\"https:\/\/wpengine.com\/builders\/wp-content\/uploads\/2024\/08\/Screenshot-2024-08-27-at-10.51.08\u202fAM-1024x547.png\" alt=\"\" class=\"wp-image-31701\" style=\"width:641px;height:auto\" srcset=\"https:\/\/wpengine.com\/builders\/wp-content\/uploads\/2024\/08\/Screenshot-2024-08-27-at-10.51.08\u202fAM-1024x547.png 1024w, https:\/\/wpengine.com\/builders\/wp-content\/uploads\/2024\/08\/Screenshot-2024-08-27-at-10.51.08\u202fAM-300x160.png 300w, https:\/\/wpengine.com\/builders\/wp-content\/uploads\/2024\/08\/Screenshot-2024-08-27-at-10.51.08\u202fAM-768x410.png 768w, https:\/\/wpengine.com\/builders\/wp-content\/uploads\/2024\/08\/Screenshot-2024-08-27-at-10.51.08\u202fAM-1536x821.png 1536w, https:\/\/wpengine.com\/builders\/wp-content\/uploads\/2024\/08\/Screenshot-2024-08-27-at-10.51.08\u202fAM-2048x1095.png 2048w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>This snippet customizes the cache keys for the <code>GetPostsWithCategoriesAndTags<\/code> operation. It removes the <code>list:tag<\/code> and <code>list:category<\/code> keys from the cache, preventing their updates from invalidating the cache for this specific query. The <code>array_diff()<\/code> function is used to filter out the unwanted keys, and the modified keys are then reassembled into a string and returned.<\/p>\n\n\n\n<p>Let\u2019s test this now in WPGraphQL IDE and the browser dev tools:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"422\" src=\"https:\/\/wpengine.com\/builders\/wp-content\/uploads\/2024\/08\/Screenshot-2024-08-27-at-10.55.57\u202fAM-1024x422.png\" alt=\"\" class=\"wp-image-31702\" srcset=\"https:\/\/wpengine.com\/builders\/wp-content\/uploads\/2024\/08\/Screenshot-2024-08-27-at-10.55.57\u202fAM-1024x422.png 1024w, https:\/\/wpengine.com\/builders\/wp-content\/uploads\/2024\/08\/Screenshot-2024-08-27-at-10.55.57\u202fAM-300x124.png 300w, https:\/\/wpengine.com\/builders\/wp-content\/uploads\/2024\/08\/Screenshot-2024-08-27-at-10.55.57\u202fAM-768x317.png 768w, https:\/\/wpengine.com\/builders\/wp-content\/uploads\/2024\/08\/Screenshot-2024-08-27-at-10.55.57\u202fAM-1536x633.png 1536w, https:\/\/wpengine.com\/builders\/wp-content\/uploads\/2024\/08\/Screenshot-2024-08-27-at-10.55.57\u202fAM-2048x844.png 2048w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>Stoked!!!&nbsp; Now as you see in the dev tools image, publishing new categories and tags, which triggers purge( <code>'list:category'<\/code> ) and purge(<code> 'list:tag'<\/code> ) will not purge this document.&nbsp;<\/p>\n\n\n\n<p>We\u2019re getting the benefits of cached GraphQL documents. The document is invalidated when the post is updated or deleted, but we\u2019re letting the cache remain cached when categories or tags are created.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Conclusion<\/h2>\n\n\n\n<p>We hope you have a better understanding of using filters, as demonstrated above, to customize your cache tagging and invalidation strategies to better suit your project&#8217;s specific needs. By taking control of how cache keys are managed, you can optimize performance and reduce unnecessary cache invalidations.<br>As always, we look forward to hearing your feedback, thoughts, and projects so hit us up in our headless <a href=\"https:\/\/discord.com\/invite\/headless-wordpress-836253505944813629\">Discord<\/a>!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Caching is important in optimizing performance for headless WordPress setups. The WPGraphQL Smart Cache plugin helps manage caching for GraphQL queries, ensuring faster response times. In this guide, we&#8217;ll walk [&hellip;]<\/p>\n","protected":false},"author":20,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_EventAllDay":false,"_EventTimezone":"","_EventStartDate":"","_EventEndDate":"","_EventStartDateUTC":"","_EventEndDateUTC":"","_EventShowMap":false,"_EventShowMapLink":false,"_EventURL":"","_EventCost":"","_EventCostDescription":"","_EventCurrencySymbol":"","_EventCurrencyCode":"","_EventCurrencyPosition":"","_EventDateTimeSeparator":"","_EventTimeRangeSeparator":"","_EventOrganizerID":[],"_EventVenueID":[],"_OrganizerEmail":"","_OrganizerPhone":"","_OrganizerWebsite":"","_VenueAddress":"","_VenueCity":"","_VenueCountry":"","_VenueProvince":"","_VenueState":"","_VenueZip":"","_VenuePhone":"","_VenueURL":"","_VenueStateProvince":"","_VenueLat":"","_VenueLng":"","_VenueShowMap":false,"_VenueShowMapLink":false,"footnotes":""},"categories":[23],"tags":[],"class_list":["post-31697","post","type-post","status-publish","format-standard","hentry","category-headless"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.3 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>How to Customize WPGraphQL Cache Keys \ud83d\udcbe\ud83d\udd11 - Builders<\/title>\n<meta name=\"description\" content=\"Learn how to customize WPGraphQL cache keys with Smart Cache in your headless WordPress setup. This step-by-step guide helps you customize your caching strategy, ensuring efficient content delivery with tailored invalidation rules.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/wpengine.com\/builders\/how-to-customize-wpgraphql-cache-keys\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"How to Customize WPGraphQL Cache Keys\" \/>\n<meta property=\"og:description\" content=\"Learn how to customize WPGraphQL cache keys with Smart Cache in your headless WordPress setup. This step-by-step guide helps you customize your caching strategy, ensuring efficient content delivery with tailored invalidation rules.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/wpengine.com\/builders\/how-to-customize-wpgraphql-cache-keys\/\" \/>\n<meta property=\"og:site_name\" content=\"Builders\" \/>\n<meta property=\"article:published_time\" content=\"2024-08-27T16:24:10+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2024-09-10T14:13:43+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/wpengine.com\/builders\/wp-content\/uploads\/2024\/08\/WPE-Builders-YouTube-WPGraphQL-OfficeHours-1920x1080@2x.png\" \/>\n\t<meta property=\"og:image:width\" content=\"3840\" \/>\n\t<meta property=\"og:image:height\" content=\"2160\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Francis Agulto\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@wpebuilders\" \/>\n<meta name=\"twitter:site\" content=\"@wpebuilders\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Francis Agulto\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"10 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/wpengine.com\\\/builders\\\/how-to-customize-wpgraphql-cache-keys\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/wpengine.com\\\/builders\\\/how-to-customize-wpgraphql-cache-keys\\\/\"},\"author\":{\"name\":\"Francis Agulto\",\"@id\":\"https:\\\/\\\/wpengine.com\\\/builders\\\/#\\\/schema\\\/person\\\/bcdcb4ac0b215c34b6b30e440a24dc54\"},\"headline\":\"How to Customize WPGraphQL Cache Keys \ud83d\udcbe\ud83d\udd11\",\"datePublished\":\"2024-08-27T16:24:10+00:00\",\"dateModified\":\"2024-09-10T14:13:43+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/wpengine.com\\\/builders\\\/how-to-customize-wpgraphql-cache-keys\\\/\"},\"wordCount\":1921,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\\\/\\\/wpengine.com\\\/builders\\\/#organization\"},\"articleSection\":[\"Headless\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/wpengine.com\\\/builders\\\/how-to-customize-wpgraphql-cache-keys\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/wpengine.com\\\/builders\\\/how-to-customize-wpgraphql-cache-keys\\\/\",\"url\":\"https:\\\/\\\/wpengine.com\\\/builders\\\/how-to-customize-wpgraphql-cache-keys\\\/\",\"name\":\"How to Customize WPGraphQL Cache Keys \ud83d\udcbe\ud83d\udd11 - Builders\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/wpengine.com\\\/builders\\\/#website\"},\"datePublished\":\"2024-08-27T16:24:10+00:00\",\"dateModified\":\"2024-09-10T14:13:43+00:00\",\"description\":\"Learn how to customize WPGraphQL cache keys with Smart Cache in your headless WordPress setup. This step-by-step guide helps you customize your caching strategy, ensuring efficient content delivery with tailored invalidation rules.\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/wpengine.com\\\/builders\\\/how-to-customize-wpgraphql-cache-keys\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/wpengine.com\\\/builders\\\/how-to-customize-wpgraphql-cache-keys\\\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/wpengine.com\\\/builders\\\/how-to-customize-wpgraphql-cache-keys\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/wpengine.com\\\/builders\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"How to Customize WPGraphQL Cache Keys \ud83d\udcbe\ud83d\udd11\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/wpengine.com\\\/builders\\\/#website\",\"url\":\"https:\\\/\\\/wpengine.com\\\/builders\\\/\",\"name\":\"Builders\",\"description\":\"Reimagining the way we build with WordPress.\",\"publisher\":{\"@id\":\"https:\\\/\\\/wpengine.com\\\/builders\\\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/wpengine.com\\\/builders\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/wpengine.com\\\/builders\\\/#organization\",\"name\":\"WP Engine\",\"url\":\"https:\\\/\\\/wpengine.com\\\/builders\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/wpengine.com\\\/builders\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/wpengine.com\\\/builders\\\/wp-content\\\/uploads\\\/2024\\\/05\\\/WP-Engine-Horizontal@2x.png\",\"contentUrl\":\"https:\\\/\\\/wpengine.com\\\/builders\\\/wp-content\\\/uploads\\\/2024\\\/05\\\/WP-Engine-Horizontal@2x.png\",\"width\":348,\"height\":68,\"caption\":\"WP Engine\"},\"image\":{\"@id\":\"https:\\\/\\\/wpengine.com\\\/builders\\\/#\\\/schema\\\/logo\\\/image\\\/\"},\"sameAs\":[\"https:\\\/\\\/x.com\\\/wpebuilders\",\"https:\\\/\\\/www.youtube.com\\\/channel\\\/UCh1WuL54XFb9ZI6m6goFv1g\"]},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/wpengine.com\\\/builders\\\/#\\\/schema\\\/person\\\/bcdcb4ac0b215c34b6b30e440a24dc54\",\"name\":\"Francis Agulto\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/0c8a05c76944fc987d57296c96dc368055844527088c0aa44297edbfa8b82546?s=96&d=mm&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/0c8a05c76944fc987d57296c96dc368055844527088c0aa44297edbfa8b82546?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/0c8a05c76944fc987d57296c96dc368055844527088c0aa44297edbfa8b82546?s=96&d=mm&r=g\",\"caption\":\"Francis Agulto\"},\"description\":\"Fran Agulto is a Developer Advocate at WP Engine. He is a lover of all things headless WordPress, Rock Climbing, and overall being stoked for people that love what they do and share that stoke with others! Follow me on Twitter for cool stoked headless WP!\",\"url\":\"https:\\\/\\\/wpengine.com\\\/builders\\\/author\\\/francis-agultowpengine-com-2-2-2-2-2-2-2-2-2-2-2-3\\\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"How to Customize WPGraphQL Cache Keys \ud83d\udcbe\ud83d\udd11 - Builders","description":"Learn how to customize WPGraphQL cache keys with Smart Cache in your headless WordPress setup. This step-by-step guide helps you customize your caching strategy, ensuring efficient content delivery with tailored invalidation rules.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/wpengine.com\/builders\/how-to-customize-wpgraphql-cache-keys\/","og_locale":"en_US","og_type":"article","og_title":"How to Customize WPGraphQL Cache Keys","og_description":"Learn how to customize WPGraphQL cache keys with Smart Cache in your headless WordPress setup. This step-by-step guide helps you customize your caching strategy, ensuring efficient content delivery with tailored invalidation rules.","og_url":"https:\/\/wpengine.com\/builders\/how-to-customize-wpgraphql-cache-keys\/","og_site_name":"Builders","article_published_time":"2024-08-27T16:24:10+00:00","article_modified_time":"2024-09-10T14:13:43+00:00","og_image":[{"width":3840,"height":2160,"url":"https:\/\/wpengine.com\/builders\/wp-content\/uploads\/2024\/08\/WPE-Builders-YouTube-WPGraphQL-OfficeHours-1920x1080@2x.png","type":"image\/png"}],"author":"Francis Agulto","twitter_card":"summary_large_image","twitter_creator":"@wpebuilders","twitter_site":"@wpebuilders","twitter_misc":{"Written by":"Francis Agulto","Est. reading time":"10 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/wpengine.com\/builders\/how-to-customize-wpgraphql-cache-keys\/#article","isPartOf":{"@id":"https:\/\/wpengine.com\/builders\/how-to-customize-wpgraphql-cache-keys\/"},"author":{"name":"Francis Agulto","@id":"https:\/\/wpengine.com\/builders\/#\/schema\/person\/bcdcb4ac0b215c34b6b30e440a24dc54"},"headline":"How to Customize WPGraphQL Cache Keys \ud83d\udcbe\ud83d\udd11","datePublished":"2024-08-27T16:24:10+00:00","dateModified":"2024-09-10T14:13:43+00:00","mainEntityOfPage":{"@id":"https:\/\/wpengine.com\/builders\/how-to-customize-wpgraphql-cache-keys\/"},"wordCount":1921,"commentCount":0,"publisher":{"@id":"https:\/\/wpengine.com\/builders\/#organization"},"articleSection":["Headless"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/wpengine.com\/builders\/how-to-customize-wpgraphql-cache-keys\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/wpengine.com\/builders\/how-to-customize-wpgraphql-cache-keys\/","url":"https:\/\/wpengine.com\/builders\/how-to-customize-wpgraphql-cache-keys\/","name":"How to Customize WPGraphQL Cache Keys \ud83d\udcbe\ud83d\udd11 - Builders","isPartOf":{"@id":"https:\/\/wpengine.com\/builders\/#website"},"datePublished":"2024-08-27T16:24:10+00:00","dateModified":"2024-09-10T14:13:43+00:00","description":"Learn how to customize WPGraphQL cache keys with Smart Cache in your headless WordPress setup. This step-by-step guide helps you customize your caching strategy, ensuring efficient content delivery with tailored invalidation rules.","breadcrumb":{"@id":"https:\/\/wpengine.com\/builders\/how-to-customize-wpgraphql-cache-keys\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/wpengine.com\/builders\/how-to-customize-wpgraphql-cache-keys\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/wpengine.com\/builders\/how-to-customize-wpgraphql-cache-keys\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/wpengine.com\/builders\/"},{"@type":"ListItem","position":2,"name":"How to Customize WPGraphQL Cache Keys \ud83d\udcbe\ud83d\udd11"}]},{"@type":"WebSite","@id":"https:\/\/wpengine.com\/builders\/#website","url":"https:\/\/wpengine.com\/builders\/","name":"Builders","description":"Reimagining the way we build with WordPress.","publisher":{"@id":"https:\/\/wpengine.com\/builders\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/wpengine.com\/builders\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/wpengine.com\/builders\/#organization","name":"WP Engine","url":"https:\/\/wpengine.com\/builders\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/wpengine.com\/builders\/#\/schema\/logo\/image\/","url":"https:\/\/wpengine.com\/builders\/wp-content\/uploads\/2024\/05\/WP-Engine-Horizontal@2x.png","contentUrl":"https:\/\/wpengine.com\/builders\/wp-content\/uploads\/2024\/05\/WP-Engine-Horizontal@2x.png","width":348,"height":68,"caption":"WP Engine"},"image":{"@id":"https:\/\/wpengine.com\/builders\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/x.com\/wpebuilders","https:\/\/www.youtube.com\/channel\/UCh1WuL54XFb9ZI6m6goFv1g"]},{"@type":"Person","@id":"https:\/\/wpengine.com\/builders\/#\/schema\/person\/bcdcb4ac0b215c34b6b30e440a24dc54","name":"Francis Agulto","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/0c8a05c76944fc987d57296c96dc368055844527088c0aa44297edbfa8b82546?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/0c8a05c76944fc987d57296c96dc368055844527088c0aa44297edbfa8b82546?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/0c8a05c76944fc987d57296c96dc368055844527088c0aa44297edbfa8b82546?s=96&d=mm&r=g","caption":"Francis Agulto"},"description":"Fran Agulto is a Developer Advocate at WP Engine. He is a lover of all things headless WordPress, Rock Climbing, and overall being stoked for people that love what they do and share that stoke with others! Follow me on Twitter for cool stoked headless WP!","url":"https:\/\/wpengine.com\/builders\/author\/francis-agultowpengine-com-2-2-2-2-2-2-2-2-2-2-2-3\/"}]}},"_links":{"self":[{"href":"https:\/\/wpengine.com\/builders\/wp-json\/wp\/v2\/posts\/31697","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/wpengine.com\/builders\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/wpengine.com\/builders\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/wpengine.com\/builders\/wp-json\/wp\/v2\/users\/20"}],"replies":[{"embeddable":true,"href":"https:\/\/wpengine.com\/builders\/wp-json\/wp\/v2\/comments?post=31697"}],"version-history":[{"count":0,"href":"https:\/\/wpengine.com\/builders\/wp-json\/wp\/v2\/posts\/31697\/revisions"}],"wp:attachment":[{"href":"https:\/\/wpengine.com\/builders\/wp-json\/wp\/v2\/media?parent=31697"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/wpengine.com\/builders\/wp-json\/wp\/v2\/categories?post=31697"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/wpengine.com\/builders\/wp-json\/wp\/v2\/tags?post=31697"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}