Debugging the cache

A Cache Miss is a request where the response could be cached but isn't. Instead, the request is passed through to the origin service. The most common reason for this is that the query response simply wasn't cached yet, because that query didn't pass through Stellate yet. Or because the previously cached response expired and was purged from the cache.

However, there are situations where a specific query passed through Stellate already, and it still isn't cached. Here are a couple of tips for looking into those issues.

Debug Header

Stellate supports a debug header called gcdn-debug. (The value you specify doesn't matter.) The presence of that header will show additional information about the request via the response headers.

If you want to give this header a try, see the following curl request that you can execute yourself. The response headers are written to a file called headers.txt, which you can open in any editor.

curl -g -X POST https://spacex-api.stellate.sh \
  -D headers.txt \
  -H "Content-Type: application/json" \
  -H "gcdn-debug: 1" \
  -d '{ "query": "{ roadster { name } }" }'

That headers.txt file will show a list of HTTP headers and their respective values, starting with the HTTP version and status code at the top. Any additional headers added by the gcdn-debug header start with gcdn and are named in a way that indicates what information they are presenting.

Among the list of headers added are the following

  • gcdn-cache indicates whether the request was a cache hit, miss or pass
  • gcdn-field-strings and gcdn-type-strings show the list of fields/types matching the response. Those would indicate which cache rules apply to the response.
  • gcdn-scopes indicate which scope (or scopes) are applied to the response
  • gcdn-origin-status-code and gcdn-origin-status-text indicate the status code (and text) sent by the backend service

The above list is not exhaustive and we might add additional headers as Stellate changes. We will try to make our naming of those headers as intuitive as possible and you can always reach out to our support team if you are unsure what a specific header is supposed to indicate.

Common reasons for cache misses or cache passes

  • A Set-Cookie header on the response will cause that request to not get cached at all. Since Stellate can't tell whether that cookie is specific to a single user, or applies to all users, we take the cautionary approach and not cache requests that also try to set a cookie. In some cases, origin servers respond with a Set-Cookie header to each request, making it impossible for us to cache anything. You can use the removeCookies configuration setting to remove certain cookies from response from your origin server. Alternatively you can also look into the configuration of your origin server and make sure those cookies aren't set in the first place.

  • If you have the "Ignore origin Cache-Control header" setting disabled Stellate respects any Cache-Control headers present on the response. This includes private, no-store. If you see more cache misses (or passes), than you expect, check that this setting is enabled (as it is by default) or check the Cache-Control headers returned by your backend and make sure they match your expectations.

  • Make sure you do not have a matching cache rule that is configured with a maxAge and swr of 0. We recommend creating those rules for types, or fields, that you do not want to cache. However, depending on your setup, they might match additional queries and cause those queries to not get cached as well. The gcdn-field-strings and gcdn-type-strings headers returned when enabling debug mode will help identifying those.

  • However, also make sure you have a matching cache rule that tells Stellate to cache that query. If no cache rule matches at all, the response will not get cached.

  • Make sure that the response is neither empty, nor an empty list. Stellate relies on the type information included with the response to tag data added to the cache. An empty list doesn't have any type information associated with it, which would make it impossible to purge that response from the cache, other than by purging the full cache. Therefore Stellate currently does not cache empty lists at all.

If none of these reasons apply to you, please reach out to us via the in app chat or via email at support@stellate.co so we can help you debug the issue.

Cache Hits with high response times

You will sometimes see Cache Hits with unusually large response times and might be wondering what triggers those.

Those cache hits are triggered if a request can't be answered from the cache, however, an identical request is already being processed. Instead of sending another request to your backend API asking for the same data, Stellate waits for the results of that initial request, and then answers the send request with the (now) already cached data.

This is technically classified as a Cache Hit, as the request was answered from the cache (in the end). However, since it had to wait on that initial request to complete, response times are higher than on regular cache hits.