Logo

dev-resources.site

for different kinds of informations.

Speeding Up Your Website Using Cloudflare Cache

Published at
8/25/2024
Categories
webdev
performance
cache
tutorial
Author
lilouartz
Categories
4 categories in total
webdev
open
performance
open
cache
open
tutorial
open
Author
9 person written this
lilouartz
open
Speeding Up Your Website Using Cloudflare Cache

Performance is critical for websites to rank in Google search results. Pillser implements a number of techniques to load and render pages quickly. However, nothing beats caching. In this post, I will share my experience with Cloudflare cache.

Cloudflare Cache

I chose Cloudflare Cache because I am already using Cloudflare for other things.

To use Cloudflare cache, I needed to:

  1. Enable Tiered Cache
  2. Enable Cache Reserve
  3. Add Cache Rules

Tiered Cache and Cache Reserve are not strictly necessary, but they enable more reliable and faster cache hits.

When you enable Cache Reserve, you are able to cache gigabytes of data. Meanwhile, Tiered Cache reduces the amount of servers that Cloudflare needs to hop through to serve your website, which improves performance, e.g. I saw cached response times go from 100ms to under 10ms when I enabled Tiered Cache.

Finally, you need to add Cache Rules to define which pages should be cached. For example, I only want to cache pages that are accessed by non-authenticated users (identified by the presence of a user_account cookie), and I only want to cache pages matching a specific URL pattern. Here is a rule that does just that:

(
  not http.cookie contains "user_account" and (
    http.request.uri.path eq "/" or
    starts_with(http.request.uri.path, "/supplements") or
    starts_with(http.request.uri.path, "/probiotics") or
    starts_with(http.request.uri.path, "/vitamins") or
    starts_with(http.request.uri.path, "/minerals") or
    starts_with(http.request.uri.path, "/brands")
  )
)
Enter fullscreen mode Exit fullscreen mode

I love that Cloudflare cache is so flexible. Their rules language is very powerful.

Cache by Device Type

You can enable options like Cache by device type if you are serving different content to different devices. Example: Pillser will render a different number of supplements per page depending on whether the user is on a mobile device or a desktop.

Once enabled, Cloudflare sends a CF-Device-Type HTTP header to your origin with a value of either mobile, tablet, or desktop for every request to specify the visitor's device type.

Utilize Strong ETags

The ETag HTTP response header is an identifier for a specific version of a resource.

Enable Respect strong ETags to ensure that the cache is invalidated when the content changes.

For this to function, you need to add a ETag header to the response. Fastify ecosystem has a plugin to automatically generate strong ETags.

Serve Stale Content While Revalidating (Not Working as Expected)

This is the only thing that I was not able to figure out.

My ideal behavior would be to cache products for a short period of time (e.g., 1 hour) and then serve stale content while revalidating.

I have therefore configured Edge TTL to Ignore cache-control header and use this TTL and set the TTL to 1 hour. This ensures that the cache becomes stale after 1 hour.

I have then left Do not serve stale content while updating disabled. This is supposed to make Cloudflare serve stale content while revalidating, but it does not seem to work.

I am still occasionally seeing content being served directly from the origin with cf-cache-status set to MISS. I would expect this to not happen, as the revalidation should happen in the background while the cache is being served. If you happen to know how to fix this, please let me know.

Lacking Features: Max Age for Stale Content

Another thing that I noticed is that Cloudflare will sometimes expire cached content based on Cache-Control headers. However, in the example of wanting to serve stale content while revalidating, I would expect that there would be a setting that allows me to explicitly say how long the content should be cached for regardless of the Cache-Control header, i.e., I would want to set max-age to several days, but require that Cloudflare revalidates the content every hour.

Effectively, I want to force Cloudflare to retain the cache beyond the TTL.

Purging Cache

Last but not least, I needed a way to purge the cache. Cloudflare provides several ways to purge the cache. However, I found that the API approach is the easiest to use:

import { config } from '#app/config.server';
import Cloudflare from 'cloudflare';

const cloudflare = new Cloudflare({
  apiEmail: config.CLOUDFLARE_API_EMAIL,
  apiKey: config.CLOUDFLARE_API_KEY,
});

const response = await cloudflare.cache.purge({
  files: ['https://pillser.com/'],
  zone_id: config.CLOUDFLARE_ZONE_ID,
});
Enter fullscreen mode Exit fullscreen mode

This allows me to automate the purging of individual product cache, e.g. when a product is updated.

Results

I ran latency tests from several locations and captured the slowest response time for each URL. The results are below:

URL Country Origin Response Time Cached Response Time
https://pillser.com/vitamins/vitamin-b1 us-west1 240ms 16ms
https://pillser.com/vitamins/vitamin-b1 europe-west3 320ms 10ms
https://pillser.com/vitamins/vitamin-b1 australia-southeast1 362ms 16ms
https://pillser.com/supplements/vitamin-b1-3254 us-west1 280ms 10ms
https://pillser.com/supplements/vitamin-b1-3254 europe-west3 340ms 12ms
https://pillser.com/supplements/vitamin-b1-3254 australia-southeast1 362ms 14ms

The results are consistent across multiple regions. It is clear that Cloudflare cache hugely improves the performance of the website, especially for users further away from the origin (US).

cache Article's
30 articles in total
Favicon
Caching in Node.js: Using Redis for Performance Boost
Favicon
Building the Perfect Caching System: A Comprehensive Guide
Favicon
Cache your function computation in React Server Components
Favicon
From Heartbeats to Cache Misses: Making Big Numbers Hit Home
Favicon
Redis Cache - A String story
Favicon
Boosting Backend Performance with Distributed Cache: A Comprehensive Guide
Favicon
๐ŸŒŸ Mastering Caching in JavaScript for Optimizing Performance ๐Ÿš€
Favicon
Cache NLogN๐ŸŽ๏ธ
Favicon
System Design 02 - Caching: The Art of Keeping Users Happy Without Breaking a Sweat
Favicon
Stale cache, the holy grail of performance
Favicon
Top 5 Caching Patterns for High-Performance Applications
Favicon
How to Effectively Handle Caching in Your Application: Lazy Loading vs Write-Through
Favicon
Using Caching in React with useGetProducts: Improve Performance and UX
Favicon
The Role of Cache Memory in Enhancing Processing Speed
Favicon
Mastering Android App Visuals: A Comprehensive Guide to Effortless Image Uploading, Storage, and Sharing.
Favicon
That way to build High-Performance APIs in .NET - Part 2: Caching
Favicon
Understanding CDN Cache in NextJs
Favicon
Supercharge your applications queries with caching
Favicon
Can Postgres replace Redis as a cache?
Favicon
Difference between cache vs cookie
Favicon
Monitor Squid Proxy with Goaccess
Favicon
Speeding Up Your Website Using Cloudflare Cache
Favicon
Finally found a solution to clear the CDN cache using GitHub Actions!
Favicon
Stale-while-revalidate and it's usage with Next.js
Favicon
Why do we need NoSql Database
Favicon
Go Redis Crud quickly example
Favicon
How to build a caching layer for your Laravel API
Favicon
Davide's Code and Architecture Notes - Cache Expiration vs Cache Eviction (and Eviction Policies)
Favicon
Entendendo porque o Cache Lock รฉ sinรดnimo de integridade
Favicon
Mastering Frontend Performance: Harnessing the Power of Caching

Featured ones: