Cache-Control, Netlify-CDN-Cache-Control, Cache Invalidation, Oh My
Tags: netlifychallenge, devchallenge, webdev, caching
Published: 2024-05-13 05:44:43

*This is a submission for the [Netlify Dynamic Site Challenge](https://dev.to/challenges/netlify): Clever Caching*


## What I Built
<!-- Share an overview about your project. -->
A website that demos how `cache-control`, `Netlify-CDN-Cache-Control` and cache tags play together.

In my reading of caching, I realize that it's so confusing to the uninitiated for several seasons:
- There are many directives that come into affecting response caching. Changing one may change the response an end user will receive.
- The interplay between these directives are not clear.
- It's hard to demonstrate the effects of these directives. Browsers and CDNs work these cache directives opaquely, which is a good thing, but the downside is that developers may not put caching to the best use.

## Demo
<!-- Share a link to your Netlify app and include some screenshots here. -->
[Link to my Netlify app](https://static-to-dynamic.netlify.app)

[Link to the repo](https://github.com/bytrangle/netlify-caching)

### Demo `cache-control`
This demo is inspired by Imgur. After you land on the home page, you get a welcome message. If you refresh the page within 60 seconds, the message remains the same. If you refresh after the 60-second interval, you'll get a new message.
This is possible by setting `max-age` directive to 60 in the `Cache-Control` field of the response header.

`max=age=60` tells browser to cache the response for 60 seconds. After this time frame, the response is stale. For assurance, I also add `must-revalidate` to `Cache-Control` to tell browsers that once the cached response has become stale, it must not be used without revalidation.

Here is the response of the request to [the cache control page](https://static-to-dynamic.netlify.app/cache-control) at 12:56:52.

![Response at 12:56:52](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/s2k0i7h9cbskyhr6bazb.png)

The clock on the bottom right is 12:56:57 because my hand couldn't hit the "take screenshot" button fast enough!

Response at 12:57:39.

![Response at 12:57:39](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4gzvy4tswy5au4o6b3t4.png)

Notice that the clock on the bottom right is 12:57:39, but the response I received is the same as the last one. Browser was using a cached response!

Response at 12:57:58.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ax3xcgtmaapi0xd0sm6f.png)

This is more than 60 seconds since the 12:56:52 timestamp. The response has changed!

### Demo for `Netlify-CDN-Cache-Control` and cache invalidation
For this demo, if you go to the [cache-tags page](https://static-to-dynamic.netlify.app/cache-tags) then refresh repeatedly, you'll likely get the same response.

I said "likely" because even though Netlify CDN was told to cache the response for 1 year, it was also instructed to always revalidate the response.

If you can't wait for the TTL (time to live) to expire, you can click the Purge button to get directed to the home page, then click the `cache-tags` page again to see the latest updated content.

[Link to video of the demo](https://streamable.com/yzglvk)

## Platform Primitives
<!-- Tell us how you leveraged Netlify Cache Control. -->
I leverage the `Netlify-CDN-Cache-Control` field in order to make Netlify CDN cache the response for up to a year. This is particularly useful on calling serverless functions that don't need to provide real-time updates.

If you have many requests to a serverless functions within a short time, only the first request calls the function. For subsequent requests, the users get cached response and the function is not called unnecessarily.

I also used `cache-tags` to label the cached content for one of my page. The I use the `purge` API to selectively purge by `cache-tags`.

<!-- Did you implement additional platform primitives like the Netlify Image CDN or Blobs? Tell us about that too! You may qualify for more than one prompt. -->

<!-- Team Submissions: Please pick one member to publish the submission and credit teammates by listing their DEV usernames directly in the body of the post. -->


<!-- Don't forget to add a cover image (if you want). -->


<!-- Thanks for participating! -->