Optimize your Caching Strategy with Storyblok
Storyblok is the first headless CMS that works for developers & marketers alike.
Caching plays a crucial role in optimizing the performance of your website or application by reducing the load on the server and decreasing page load times. In this article, we will delve into the caching mechanism of Storyblok to understand how it works and how you can make the most of it.
What does “caching” mean?
Caching is the process of storing and reusing data or content so that it can be quickly retrieved when requested again. Instead of generating content from scratch every time a user requests it, a cached copy is served, significantly reducing the server's load and speeding up the response time.
Speaking of Storyblok, the product and its services are stored on Amazon AWS, using efficient data centers located in different parts of the world to manage and deliver the content. But Storyblok also uses a content delivery network (CDN) in front of the API to cache the content, in order to achieve low latencies all over the world and deliver content in the fastest way possible. Storyblok uses Amazon CloudFront as its CDN.
What is cached in Storyblok?
The content retrieved by connecting to the Content Delivery API is cached. Storyblok routes each first-time request to one of the main data sources. All subsequent calls are cached in the CDN endpoints and delivered with very low latency.
The assets managed in the Assets Library are also cached. Images, videos, documents, and other static assets are kept in the CDN as long as possible. The same happens with the image variations generated using Storyblok’s Image Service.
You can read more details in this article.
How does caching work in Storyblok?
Speaking about the content delivered by the Content Delivery API, Storyblok appends a parameter called cv
which means "cache version". This parameter is an integer value that contains a Unix timestamp. The cache version is always updating whenever you publish any new content in Storyblok.
You can retrieve the most updated cv
value for your space by doing an API call without providing the cv
parameter:
/v2/cdn/spaces/me/?token=[YOUR_TOKEN]
While you can call any API endpoint, we recommend using /v2/cdn/spaces/me/
for performance purposes. After you get the response to your call, check the body for the cv
attribute. Save it in memory and use it for subsequent requests in order to get the latest version of the content.
To apply cache invalidation, you would need to keep the cv
value stored in memory up-to-date. In order to do that, you can apply different approaches:
- Receive an automatic update by a webhook call that is triggered whenever the content is published, updated, or deleted.
- Fetch it every time you boot up your application.
- Create a serverless function that runs periodically, invalidating the cache.
- Etc.
If you are using one of the official Storyblok SDKs in your project, which are based on the storyblok-js-client, there is no need to worry about the cv parameter: They already take care of cache invalidation for you.
Read more on the API docs.
Why is caching important?
Besides the reasons previously mentioned (low latency, better performance, etc), you should consider managing cached content in order to stay within Storyblok’s rate limits. The content delivery API has a rate limit of 50 requests per second for uncached requests, while the limit is 1000+ requests per second for cached content. You can read more about this on the API docs.
Caching & Rendering
Another aspect to evaluate when defining a caching policy is the way your project will consume and render the content.
If you are using server-side or client-side rendering, you have to consider that your application will fetch data from the data sources (like Storyblok) for every request sent by the users. In a case like this, it’s crucial to define a caching logic that reduces the amount of requests that the backend will have to actually process. In the meantime, you should also evaluate how often the data and the content are updated, and how that affects the whole user experience of your project, so you can define how frequently the cache will have to be invalidated.
On the other hand, if you use a framework that implements static site generation, the cache policy will still be important but not as crucial as with the other methods. The build process that generates the static content of your website will run on a unique location, and with a defined frequency. The data sources will be acceded by this build process, instead of having multiple users querying them. So, it would make more sense that the globally distributed cache logic you implement is on top of the already generated static assets, instead of the actual data used to generate the pages.
Optimizing Storyblok Caching
Set Appropriate Cache Durations
Tailor the cache duration for your content based on how frequently it changes. Static content can have a longer cache duration, while dynamic content should have a shorter one.
Use Webhooks Effectively
Ensure that your webhooks are properly configured to trigger cache invalidation when content changes. This guarantees that your users always see the latest content.
Implement Browser Caching
Implement browser caching headers for assets like images, stylesheets, and JavaScript files. This instructs the user's browser to cache these assets locally, reducing server load and improving page load times.
Use a CDN in front of Storyblok
Consider using a CDN or another backend layer in conjunction with Storyblok to further optimize content delivery.
Check Amazon CloudFront headers
You can check Amazon CloudFront headers and verify whether a request resulted in a HIT or a MISS.
- Open Developer Tools
- Navigate to the Network tab
- Reload the page
- Select the request made to the Storyblok API
- View the Headers of the request
To determine whether the request resulted in a HIT or a MISS, focus on the response headers. In particular, you should look for the x-cache
header. This header indicates the caching behavior for the CloudFront distribution:
- If the
x-cache
header contains the valueHit from cloudfront
it means that the request resulted in a HIT, indicating that the content was served from the CloudFront cache. - If the
x-cache
header contains the valueMiss from cloudfront
it means that the request resulted in a MISS, indicating that CloudFront had to fetch the content from Storyblok’s data center because it was not present in the cache.
Conclusion
Understanding and optimizing the caching mechanism in Storyblok is essential for delivering fast and responsive websites and applications. By employing effective caching strategies, you can strike a balance between serving fresh content and improving performance, ultimately enhancing the user experience.