Skip to content

Caching

Caching is the process of storing data so that future requests for that data can be served faster. Instead of generating a response from scratch for every request, a cached copy is served, reducing the load on the server and speeding up response times. To deliver content and assets as fast as possible, Storyblok leverages a content delivery network (CDN) powered by Amazon CloudFront.

Storyblok's CDN caches two types of data at endpoints around the world, each for up to one year:

  • Content: Content Delivery API responses for requests of published content.
  • Assets: Images, videos, documents, and other static files, including image variations generated by the Image Service.

The CDN caches Content Delivery API responses, reducing latency and offloading traffic from the backend. Understanding how this cache works, and how to use it effectively, is essential for building performant websites and applications that stay within the API's rate limits.

The Content Delivery API enforces rate limits on uncached requests. For example, the limit for single stories is 50 per second, whereas the limit for requests containing 75 to 100 stories is 6 per second. In contrast, cached requests from the CDN allow over 1000 requests per second. Find the complete rate limit table in the Content Delivery API reference. Maximizing cache usage is the most effective way to stay within these limits.

To ensure a high cache hit rate for published content, Storyblok uses the cv parameter. Every response from the Content Delivery API contains such a cv property. The cv is a space-specific numeric counter (a Unix timestamp) that increments with each content change within the space. It serves as a cache key: requests that include a cv parameter are served directly from the CDN.

Under certain conditions, the API automatically redirects requests without a cv to the stories endpoint with the latest cv value:

  • When the request is made without a cv parameter
  • When the request is made with an outdated cv value and that version has never been requested before (i.e., it has never been cached in the CDN)
  • When the request is made with an invalid cv value
GET https://api.storyblok.com/v2/cdn/stories?token=[PUBLIC_ACCESS_TOKEN]
# 301 Redirect
GET https://api.storyblok.com/v2/cdn/stories?cv=1735645795&token=[PUBLIC_ACCESS_TOKEN]

If this exact request is made for the first time, the response is then cached in the CDN. Any subsequent request with the same cv value is served directly from the cache without hitting the backend.

While the stories, datasources, and datasource entries endpoints of the Content Delivery API return the current cv value, the most efficient way to retrieve it is via the spaces endpoint:

GET https://api.storyblok.com/v2/cdn/spaces/me?token=[PUBLIC_ACCESS_TOKEN]
{
"space": {
"id": 123456,
"name": "Storyblok",
"domain": "https://www.storyblok.com/",
"version": 1544117388
}
}

The version property in the response is the latest cv value. Use it as the cv query parameter in all subsequent API calls to maximize cache usage.

When new content is published, the version value updates, but previous responses remain cached under the old cv. To retrieve up-to-date content, fetch the updated version and use it as the new cv parameter.

Fetching, storing, and invalidating the cv parameter should be part of your application architecture. Use cron jobs, custom events, or Storyblok's webhooks to detect when to retrieve a new cv.

The CDN caches assets uploaded to Storyblok, as well as optimized image variations generated by the Image Service. This caching mechanism ensures that assets are delivered quickly to users. Assets are first served from the origin, and subsequent requests are cached on the CDN to minimize latency. Refer to the assets concept for further information.

The CDN also caches image variations created on demand using the Image Service. Once a particular variation has been requested for the first time, it is cached. Refer to the Image Service documentation for further information.

An asset's cache does not need to be cleared unless it is replaced or changed (for example, using Storyblok's Image Editor or the Replace Assets app). In these scenarios, the cache is automatically invalidated. The new version is served on the next request, and cached hereafter.

The following strategies help optimize API usage and cache performance. Each strategy addresses a different aspect of caching, and combining several of them yields the best results.

First and foremost, always include the cv in API requests. This is the single most effective optimization.

Use Storyblok's webhooks to detect content changes and trigger cache invalidation in your application. For example, trigger a webhook whenever a story is published, updated, moved, or deleted to update the cv to the most up-to-date value. Refer to the webhooks developer concept for further information.

Setting a time to live (TTL) is most effective for high-traffic projects that send many requests to the Content Delivery API and update content frequently. It reduces uncached API calls and lowers response times. However, it introduces a trade-off: content updates are not reflected until the TTL expires and a new change occurs.

By default, the cv value changes with every content update, which means previously cached responses become stale immediately. The TTL setting for public access tokens overrides this behavior by making the cv persist for a defined duration. Refer to the access tokens developer concept for further information.

Setting a TTL value (in seconds) on a public access token freezes the cv for that duration. During the TTL window, all API requests using that token receive the same cv. Therefore, all responses are served from the cache.

After the TTL window has expired, the cv is not updated automatically. The next content change triggers a new cv. The first API request after that change retrieves fresh content and creates a new cache entry.

For example, a TTL of 300 seconds (five minutes) means:

  1. The first request retrieves content and caches it with the current cv.
  2. For the next five minutes, all requests receive the cached response, with the exact same content — even if content changes in the meantime.
  3. After five minutes, the next content change generates a new cv, and the first subsequent request creates a fresh cache.

Consider that the rendering mode of your application determines how and when API requests are made, which directly affects caching behavior:

  • Client-side rendering (CSR) and server-side rendering (SSR): The application fetches data for every user request. Implement a caching strategy that reduces the number of requests the backend processes. Consider how often your content changes to determine cache invalidation frequency.
  • Static site generation (SSG): During the build process, all content is fetched at once, which can be aggressive on rate limits. To avoid rate limit issues, using the multiple stories endpoint rather than the single story endpoint is preferable. Consider that some static builds are executed with multiple workers, which may impact the benefits of the cv.

As explained further under cache version, the cv is space-specific rather than story-specific.

Track request volume and rate limit status to detect potential issues before they affect your application. Use the space dashboard to monitor consumption metrics. Refer to the space dashboard user manual for further information. Additionally, in your application, log rate limit errors.

With a solid caching strategy in place, operating within Storyblok's rate limits should be the norm. Nevertheless, it is advisable to implement retry logic with exponential backoff to handle HTTP 429 responses gracefully.

For greater control over asset caching, consider setting up a custom assets domain. This allows to defining custom cache headers and TTL policies, and leveraging any existing CDN infrastructure. Refer to the custom assets domain documentation for setup guides.

Beyond Storyblok's CDN, consider implementing cache layers in your own application. Browser caching reduces redundant network requests for returning visitors. Application-level caching — for example, storing API responses in memory or in a key-value store — reduces the number of requests to Storyblok's API during server-side rendering or build processes. Set cache durations based on how often your content changes and use webhooks to invalidate stale entries.

Storyblok's JavaScript-based framework SDKs use the JavaScript client, which handles the cv parameter automatically. When the application makes its first API call to the /stories/ endpoint, the client stores the version number from the response in memory and reuses it for all subsequent calls.

Override the cached cv by passing a custom value in an API request:

import StoryblokClient from "storyblok-js-client";
const Storyblok = new StoryblokClient({
accessToken: "PUBLIC_ACCESS_TOKEN",
});
const response = await Storyblok.getStory("home", {
version: "published",
cv: "1735815318",
});

The client caches this value. Subsequent calls without a custom cv parameter reuse it:

// Results in GET /stories/home?cv=1735815318&version=published&token=[YOUR_TOKEN]
const response = await Storyblok.getStory("home", {
version: "published",
});

Call the flushCache() method to clear the client's in-memory cache:

await Storyblok.flushCache();

Passing a cv parameter equal to the current timestamp bypasses the CDN cache entirely, because the requested version is always newer than the latest cached version. Note that this forces every request to hit the backend and count against the rate limit.

const response = await Storyblok.getStory("home", {
version: "published",
cv: Date.now(),
});

Alternatively, calling the /stories/ endpoint with version: "draft" flushes the client cache. Use this approach only in preview or development environments.

Was this page helpful?

What went wrong?

This site uses reCAPTCHA and Google's Privacy Policy (opens in a new window) . Terms of Service (opens in a new window) apply.