Cache Rules

The Stellate Edge Cache gives you fine-grained per-type or even per-field control over your cache behavior for every single query that is sent through your service with cache rules.

GraphQL edge cache configuration basics

A basic rule to cache all queries that contain any User could look like this:

{
  "types": [
    "User"
  ],
  "maxAge": 900,
  "swr": 900,
  "scope": "AUTHENTICATED",
    "description": "Cache Users"
}

A rule applies to all queries that contain the rule's types or fields. If multiple rules apply to the same query, Stellate will use the minimum maxAge, the minimum swr, and combine all scopes to cache the query result.

types (required)

The rule will apply its cache configuration to any query that contains the types or fields mentioned in the types property.

You can target both types as well as specific fields of types:

"types": {
    // This rule will apply to any query that contains any User
  "User": true
  
  // This rule will apply to any query that contains Post.comments
  "Post": [
    "comments"
  ]

  // This rule will apply to any "{ drafts }" query
  // (assuming the "Query" type is the root schema query type)
  "Query": [
    "drafts"
  ]
}

maxAge (seconds, optional)

The maxAge parameter configures how long query results that match the rule types should be cached, in seconds. If multiple rules apply to the same query, the minimum maxAge will be used for the entire query result.

🚧

If you want to make sure that a specific type is never cached, define a cache rule targeting that type and set its maxAge (and swr) to 0

swr (stale-while-revalidate, seconds, optional)

The "swr" (stale-while-revalidate) property configures how long stale query results that match the rule types should be served while fresh data is already being fetched in the background.

For example, if you set the maxAge of a query to 60s and swr to 300s, depending on when new requests come in the following actions are taken:

  1. Within the first 60 seconds, the cached result will be returned from our edge locations.
  2. From 60s to 360s we will pass on the first request to your backend service, but continue to serve the cached (but stale) results for other identical requests. As soon as we get an updated response from your backend service we will update the cached data.
  3. Any requests coming in later than 360s will get passed on to your backend service. The first response will re-populate the cache.

We would recommend always configuring stale-while-revalidate, as well as keeping the swr limits fairly high. Your users will get a very quick response to their request, while we load potentially updated data in the background and update the cache.

If you want to read more about this topic, please see Keeping things fresh with stale-while-revalidate by Jeff Posnick.

scope (string, optional)

Which scope to apply to query results that match the rule types. See the documentation on Scopes for more information on setting up scopes.

description (string, optional)

Description of the purpose of the rule in plain English.

FAQ

How do I cache every GraphQL query?

To apply a rule to everything, target the root Query type:

{
  "types": [
    "Query"
  ],
  "maxAge": 900,
  "swr": 900,
    "description": "Cache everything"
}

Since the Query type is included in every single query, this rule will apply to all queries. Note that creating a rule that targets the Query type sets a maximum maxAge and swr for all rules! Since Stellate always uses the minimum maxAge and swr of all the rules that apply to a single query, and this rule applies to all queries, you can never increase the maxAge and swr of any cached query result to more than 900 (in this example).

How to not cache a type

If you want to make sure a specific type (or field) is not getting cached at all, you can configure a new cache rule targeting that type and setting the maxAge and swr fields to 0.

{
  "types": [
    "User"
  ],
  "maxAge": 0,
  "swr": 0,
    "description": "Cache everything"
} 

What happens when multiple rules apply to the same GraphQL query?

Stellate will use the minimum maxAge, and the minimum swr and combine all scopes to cache the query result.

For example, imagine you have these two rules defined:

"rules": [
  {
    "types": [
        "Posts"
    ],
    "maxAge": 900,
      "swr": 900,
        "description": "Cache Posts publicly"
    },
  {
    "types": [
      "User"
    ],
    "maxAge": 450,
    "swr": 1000,
    "scope": "AUTHENTICATED",
        "description": "Cache User data privately"
    }
]

And send a query that contains a User and a Post, which means both rules apply:

{
  user(id: "...") { 
    id 
    posts(first: 10) { 
      id 
    }
  }
}

Then the query result would be cached with a 450s maxAge (the minimum of both rules), a 900s swr (the minimum of both rules) as well as with a scope of AUTHENTICATED (the combination of all the scopes applied via the rules).