Caching and invalidation of data connections

When configuring a data type an option enabling caching of its resources is turned on by default.

The default "time-to-live" (how long a resource will be cached) is 30 seconds. This is a reasonable value for frequently changed and frequently accessed data: in the worst-case scenario a user gets information that's outdated 30s or less while the load on the service providing the data is significantly reduced (the more traffic you get, the better result you get).

When configuring a Data Type an option enabling caching of its resources is turned on by default.

But the longer cache TTL is, it becomes more and more important to have the ability to purge caches when the change happens. Cache purging should be implemented when the selected TTL protects the origin from excess requests but the stale responses aren't an acceptable tradeoff.

In the “Advanced options” of a data type you can grab a “purge key” (see the screenshot above). It can be used with two endpoints:

  • /api/v1/invalidation to purge data resources of one Data Type
  • /api/v1/batch-invalidation to purge data resources of multiple Data Types

Both endpoints are documented at

To make things easier, you can use the “Purge cache” option on the Data Type listing page. It allows generating fetch or curl code that will purge caches based on provided conditions, including a valid purge key.

Use 'Purge cache' option to generate API calls purging Edge caches

First, set up a test data type using JSON placeholder (

Use 'Getting one to do' from the API, with one variable called `id`

Now you can create a composition with two data resources of this Data Type; let’s use ID=1 for the first one and ID=2 for the other one. Once done, you can fetch the composition with the API or using @uniformdev/canvas. Then you'll attach the diagnostics=true request parameter so you can see what’s happening under the hood.

With caches warmed up, you’ll see both data resources are fetched from cache (cacheHit):

[ { "componentPath": ".", "dataName": "todos Content", "performance": { "cacheHit": true, ... }, "data": {...}, "dataType": "todos" }, { "componentPath": ".", "dataName": "todos Content 2", "performance": { "cacheHit": true, ... }, "data": {...}, "dataType": "todos" } ]

Using the “Purge cache” option, you can generate a curl command that will invalidate all caches for a data type:

curl \ -X POST \ -H 'x-purge-key: your-purge-key-here' \ ''

After issuing this call, you’ll see both cacheHit will turn to false. But let’s simulate only one of the to dos has changed: in this situation, the back-end system would make a call to invalidate based on the variable value:

curl \ -X POST \ -H 'x-purge-key: your-purge-key-here' \ -H 'content-type: application/json' \ -d '{"variables":[{"name":"id","value":"1"}]}' \ '' // Composition after this call: [ { "componentPath": ".", "dataName": "todos Content", "performance": { "cacheHit": false, ... }, "data": {...}, "dataType": "todos" }, { "componentPath": ".", "dataName": "todos Content 2", "performance": { "cacheHit": true, .... }, "data": {...}, "dataType": "todos" } ]

If your data type endpoint responds with x-uniform-surrogate-keys header, the values attached to a response can be used for purging. The value of the header should be a list of comma-separated values (multiple surrogate keys allowed).

Assuming an endpoint serving your Data Type responded with x-uniform-surrogate-keys=product-123 , the back-end system can later invalidate the cached version with the following call:

curl \ -X POST \ -H 'x-purge-key: your-purge-key-here' \ -H 'content-type: application/json' \ -d '{"surrogateKeys":["product-123"]}' \ ''

In the future Uniform will allow integrations to declare how surrogate keys should be computed. Currently it’s only implemented for the updated Mesh Contentful integration. It will automatically attach surrogate keys for all the related entities in the format of EntityType:entityId , for example: Asset:my-image or Entry:product-123.

This means that a webhook can be configured for automatic cache invalidation when Content at Contentful changes: