# Cache tags in CDA responses

Every response from the Content Delivery API can return the list of cache tags associated with the query and its results. This page covers how to request them, how they are encoded, and the limits they respect.

## Requesting cache tags

To access the cache tags, simply add the following header to your existing GraphQL POST requests:

```plaintext
X-Cache-Tags: true
```

With this new header included (and the use of the `--include` flag to show HTTP headers), a CURL request would look like this:

```plaintext
$ curl 'https://graphql.datocms.com/' \
    -H 'Authorization: YOUR-API-TOKEN' \
    -H 'Content-Type: application/json' \
    -H 'Accept: application/json' \
    -H 'X-Cache-Tags: true' \
    --include \
    --data-binary '{ "query": "query { allPosts { title } }" }'
```

> [!PROTIP]
> The `X-Cache-Tags` is one of many headers you can use to shape up the behavior of the Content Delivery API. Refer to the related section for more information on the other [available headers in the Content Delivery API](https://www.datocms.com/docs/content-delivery-api/api-endpoints.md) endpoint.

The response (omitting what's not related to cache tags) will include a new `X-Cache-Tags` header:

```http
HTTP/2 200
...
X-Cache-Tags: BQD?* 2.a*q f7e N*r;L 6-KZ@ t#k[uP t#k[ub t#k[uU
...

{
  "data": {
    "allPosts": [ ... ]
  }
}
```

The `X-Cache-Tags` that appears in the response is a space-separated list of strings: each string represents a cache tag, carefully generated to cover all possible invalidation scenarios.

> [!POSITIVE] Cache tags are not readable, and that's a good thing!
> DatoCMS provides cache tags that are intentionally opaque, to prevent misinterpretation and misuse on your end. Cache invalidation is a complicated process with a high possibility of errors and overlooking specific edge-cases. Our cache tags help us handle these complexities for you. Their non-transparent nature also allows us the flexibility to improve our tagging strategies in the future, without necessitating changes on your frontend.

## Encoding

Cache tags are supposed to be opaque to the user, which means you don't have to know the meaning conveyed by each tag to use it. However, it may be useful to know and consider the encodings of the tags so that you can make sure they work properly across your tech stack.

Each tag is a string encoded using an alphabet of 66 symbols:

```plaintext
!"#$%&@'()*+-./0123456789:;<=>?[\]^_abcdefghijklmnopqrstuvwxyz{|}~
```

Note that the alphabet contains **no spaces, no commas, and no uppercase letters**. Tags are therefore safe to concatenate into the comma-separated or space-separated header formats used by every major CDN, and they stay unambiguous on CDNs that treat cache tags case-insensitively (such as Netlify).

> [!NOTE] Potential future encoding updates
> We strive to ensure our cache tags are compatible with as many CDNs as possible. If we need to modify the encoding to support additional CDNs in the future, we'll handle the transition smoothly. Should such a change occur, we'll automatically send an invalidation event through your existing webhook configuration, allowing your system to adapt without any manual intervention required.

## Limits

To ensure cache tags work across all major CDNs, DatoCMS enforces two limits on every Content Delivery API response:

-   **A maximum of 500 cache tags per response.** This is the lowest common denominator among the CDNs that support tag-based invalidation.
-   **A maximum of ~14 KB for the serialized** **`X-Cache-Tags`** **header.** Most CDNs cap the size of individual response headers (Cloudflare, for example, allows 16 KB per header and 32 KB in total), and we leave room for the rest of your response headers.
    

###### Granularity of cache tags

A response's cache tags cover all the content its query returns, so the more content a query returns, the more often that response is invalidated.

Count the tags in the `X-Cache-Tags` header to see where a query stands. A response that comes back with the maximum of 500 tags is the case worth acting on: it will be invalidated substantially more often than its content actually requires. Fetching fewer records per query — by paginating, or by splitting one large query into several smaller ones — makes invalidation more precise.

## Related content in "Content Delivery API"

- [Content Delivery API Overview](https://www.datocms.com/docs/content-delivery-api.md)
- [Using the JavaScript CDA client](https://www.datocms.com/docs/content-delivery-api/your-first-request.md)
- [Authentication and permissions](https://www.datocms.com/docs/content-delivery-api/authentication.md)
- [Configuring requests: envs, drafts, strict mode, cache tags, etc.](https://www.datocms.com/docs/content-delivery-api/api-endpoints.md)
- [How to fetch records](https://www.datocms.com/docs/content-delivery-api/how-to-fetch-records.md)
- [Filtering records](https://www.datocms.com/docs/content-delivery-api/filtering-records.md)
- [Deep Filtering](https://www.datocms.com/docs/content-delivery-api/deep-filtering.md)
- [Ordering records](https://www.datocms.com/docs/content-delivery-api/ordering-records.md)
- [Pagination](https://www.datocms.com/docs/content-delivery-api/pagination.md)
- [Localization](https://www.datocms.com/docs/content-delivery-api/localization.md)
- [Direct vs. Inverse relationships](https://www.datocms.com/docs/content-delivery-api/inverse-relationships.md)
- [Hierarchical sorting (Tree-like collections)](https://www.datocms.com/docs/content-delivery-api/hierarchical-sorting.md)
- [Modular content fields](https://www.datocms.com/docs/content-delivery-api/modular-content-fields.md)
- [Structured text fields](https://www.datocms.com/docs/content-delivery-api/structured-text-fields.md)
- [Images and videos](https://www.datocms.com/docs/content-delivery-api/images-and-videos.md)
- [Filtering uploads](https://www.datocms.com/docs/content-delivery-api/filtering-uploads.md)
- [SEO and favicon fields](https://www.datocms.com/docs/content-delivery-api/seo-and-favicon.md)
- [Meta fields](https://www.datocms.com/docs/content-delivery-api/meta-fields.md)
- [Cache Tags Overview](https://www.datocms.com/docs/content-delivery-api/cache-tags.md)
- [Cache tags in CDA responses](https://www.datocms.com/docs/content-delivery-api/cache-tags-format.md)
- [The cache tags invalidation webhook](https://www.datocms.com/docs/content-delivery-api/cache-tags-invalidation.md)
- [Integrating cache tags in your project](https://www.datocms.com/docs/content-delivery-api/cache-tags-integrations.md)
- [Error codes & handling failures (CDA)](https://www.datocms.com/docs/content-delivery-api/errors.md)
- [CDA Technical Limits & Rate Limits](https://www.datocms.com/docs/content-delivery-api/technical-limits.md)
- [Complexity](https://www.datocms.com/docs/content-delivery-api/complexity.md)
- [Custom Scalar Types](https://www.datocms.com/docs/content-delivery-api/custom-scalar-types.md)
- [Changelog](https://www.datocms.com/docs/content-delivery-api/changelog.md)