From 69557c0fda93cbc7bc3cae39592f564ea47380c4 Mon Sep 17 00:00:00 2001 From: conico974 Date: Wed, 19 Mar 2025 14:14:29 +0100 Subject: [PATCH 1/4] add docs for the new tag cache options --- pages/cloudflare/caching.mdx | 133 ++++++++++++++++++++++++++++++++++- 1 file changed, 132 insertions(+), 1 deletion(-) diff --git a/pages/cloudflare/caching.mdx b/pages/cloudflare/caching.mdx index 8814995..5bb7bec 100644 --- a/pages/cloudflare/caching.mdx +++ b/pages/cloudflare/caching.mdx @@ -1,5 +1,6 @@ import { SITE } from "../../config"; import { Callout } from "nextra/components"; +import { Tabs } from "nextra/components"; ## Caching @@ -79,12 +80,139 @@ export default defineCloudflareConfig({ #### On-Demand Revalidation -The tag revalidation mechanism uses a [Cloudflare D1](https://developers.cloudflare.com/d1/) database as its backing store for information about tags, paths, and revalidation times. +The tag revalidation mechanism can use either a [Cloudflare D1](https://developers.cloudflare.com/d1/) database or [Durable Objects](https://developers.cloudflare.com/durable-objects/) with SqliteStorage as its backing store for information about tags, paths, and revalidation times. To use on-demand revalidation, you should also follow the [ISR setup steps](#incremental-static-regeneration-isr). If your app **only** uses the pages router, it does not need to have a tag cache and should skip this step. + You can also skip this step if you don't want to use `revalidateTag` or `revalidatePath` in your app. + + +There is 3 different options to choose from for the tag cache: 'd1NextTagCache', `ShardedTagCache` and `d1TagCache`. +For a small to medium size project, `d1NextModeTagCache` is recommended, for bigger projects `ShardedTagCache` is recommended. + + + +##### 1. Create a D1 database and Service Binding + +The binding name used in your app's worker is `NEXT_CACHE_D1`. The service binding should be a self reference to your worker where `` is the name in your wrangler configuration file. + +```jsonc +// wrangler.jsonc +{ + // ... + "d1_databases": [ + { + "binding": "NEXT_CACHE_D1", + "database_id": "", + "database_name": "", + }, + ], + "services": [ + { + "binding": "NEXT_CACHE_REVALIDATION_WORKER", + "service": "", + }, + ], +} +``` + +##### 2. Create table for tag revalidations + +The D1 tag cache requires 1 table that tracks On-Demand revalidation times. + +The default table name is `revalidations` and can be configured by setting the `NEXT_CACHE_D1_REVALIDATIONS_TABLE` environment variable to a string. + +Wrangler can be used to create a table with it's [execute](https://developers.cloudflare.com/d1/wrangler-commands/#d1-execute) option. Ensure that you create a table for both your local dev database and your remote database. + +```sh +wrangler d1 execute NEXT_CACHE_D1 --command "CREATE TABLE IF NOT EXISTS revalidations (tag TEXT NOT NULL, revalidatedAt INTEGER NOT NULL, UNIQUE(tag) ON CONFLICT REPLACE)" +``` + +##### 3. Configure the cache + +In your project's OpenNext config, enable the KV cache and set up a queue (see above). The queue will send a revalidation request to a page when needed, but it will not dedupe requests. + +```ts +// open-next.config.ts +import { defineCloudflareConfig } from "@opennextjs/cloudflare"; +import kvIncrementalCache from "@opennextjs/cloudflare/kv-cache"; +import d1NextTagCache from "@opennextjs/cloudflare/d1-next-tag-cache"; +import memoryQueue from "@opennextjs/cloudflare/memory-queue"; + +export default defineCloudflareConfig({ + incrementalCache: kvIncrementalCache, + tagCache: d1NextTagCache, + queue: memoryQueue, +}); +``` + + + + +##### 1. Create a Durable Object and Service Binding +The service binding should be a self reference to your worker where `` is the name in your wrangler configuration file. + +```jsonc +// wrangler.jsonc +{ + // ... + "durable_objects": [ + { + "name": "NEXT_CACHE_REVALIDATION_DURABLE_OBJECT", + "class_name": "DurableObjectQueueHandler", + }, + { + "name": "NEXT_CACHE_D1_SHARDED", + "class_name": "DOShardedTagCache", + }, + ], + "migrations": [ + { + "tag": "v1", + "new_sqlite_classes": ["DurableObjectQueueHandler", "DOShardedTagCache"], + }, + ], + "services": [ + { + "binding": "NEXT_CACHE_REVALIDATION_WORKER", + "service": "", + }, + ], +} +``` + +##### 2. Configure the cache + +In your project's OpenNext config, enable the KV cache and set up a queue. The queue will send a revalidation request to a page when needed, but it will not dedupe requests. + +```ts +// open-next.config.ts +import { defineCloudflareConfig } from "@opennextjs/cloudflare"; +import kvIncrementalCache from "@opennextjs/cloudflare/kv-cache"; +import shardedTagCache from "@opennextjs/cloudflare/do-sharded-tag-cache"; +import memoryQueue from "@opennextjs/cloudflare/memory-queue"; + +export default defineCloudflareConfig({ + incrementalCache: kvIncrementalCache, + tagCache: shardedTagCache({ numberOfShards: 12, regionalCache: true }), + queue: memoryQueue, +}); +``` + +ShardedTagCache accepts 3 options: + +- `numberOfShards` - The number of shards to use for the cache. The more shards you have, the more evenly the cache will be distributed across the shards. The default is 4. +- `regionalCache` - Whether to use regional cache for the cache. The default is false. This option is useful when you want to reduce the stress on the durable object. +- `regionalCacheTTL` - The TTL for the regional cache. The default is 5 seconds. Increasing this value will increase the time it takes for the cache to be invalidated across regions. + + + + + + + The `d1TagCache` is not recommended for production use, as it does not scale well with the number of tags. ##### 1. Create a D1 database and Service Binding @@ -155,3 +283,6 @@ wrangler d1 execute NEXT_CACHE_D1 --file .open-next/cloudflare/cache-assets-mani ``` This should be run as part of each deployment to ensure that the cache is being populated with each build's initial revalidation data. + + + From 075c081bb5b092da4c85794f2b8f58aacf0dfcf6 Mon Sep 17 00:00:00 2001 From: conico974 Date: Wed, 19 Mar 2025 14:53:03 +0100 Subject: [PATCH 2/4] Apply suggestions from code review Co-authored-by: Victor Berchet --- pages/cloudflare/caching.mdx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pages/cloudflare/caching.mdx b/pages/cloudflare/caching.mdx index 5bb7bec..c593f4a 100644 --- a/pages/cloudflare/caching.mdx +++ b/pages/cloudflare/caching.mdx @@ -80,16 +80,16 @@ export default defineCloudflareConfig({ #### On-Demand Revalidation -The tag revalidation mechanism can use either a [Cloudflare D1](https://developers.cloudflare.com/d1/) database or [Durable Objects](https://developers.cloudflare.com/durable-objects/) with SqliteStorage as its backing store for information about tags, paths, and revalidation times. +The tag revalidation mechanism can use either a [Cloudflare D1](https://developers.cloudflare.com/d1/) database or [Durable Objects](https://developers.cloudflare.com/durable-objects/) with `SqliteStorage` as its backing store for information about tags, paths, and revalidation times. To use on-demand revalidation, you should also follow the [ISR setup steps](#incremental-static-regeneration-isr). If your app **only** uses the pages router, it does not need to have a tag cache and should skip this step. - You can also skip this step if you don't want to use `revalidateTag` or `revalidatePath` in your app. + You can also skip this step if your app doesn't to use `revalidateTag` nor `revalidatePath`. -There is 3 different options to choose from for the tag cache: 'd1NextTagCache', `ShardedTagCache` and `d1TagCache`. +There are 3 different options to choose from for the tag cache: 'd1NextTagCache', `ShardedTagCache` and `d1TagCache`. For a small to medium size project, `d1NextModeTagCache` is recommended, for bigger projects `ShardedTagCache` is recommended. From 152d608b7388f0fe03b4cf1e552d8691dafd5f85 Mon Sep 17 00:00:00 2001 From: conico974 Date: Thu, 20 Mar 2025 15:40:41 +0100 Subject: [PATCH 3/4] review --- pages/cloudflare/caching.mdx | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/pages/cloudflare/caching.mdx b/pages/cloudflare/caching.mdx index c593f4a..32d72a0 100644 --- a/pages/cloudflare/caching.mdx +++ b/pages/cloudflare/caching.mdx @@ -90,7 +90,12 @@ To use on-demand revalidation, you should also follow the [ISR setup steps](#inc There are 3 different options to choose from for the tag cache: 'd1NextTagCache', `ShardedTagCache` and `d1TagCache`. -For a small to medium size project, `d1NextModeTagCache` is recommended, for bigger projects `ShardedTagCache` is recommended. +Which one to choose should be based on two key factors: + +1. **Expected Load**: Consider the volume of traffic or data you anticipate. +2. **Usage of** `revalidateTag` / `revalidatePath`: Evaluate how frequently these features will be utilized. + +If either of these factors is significant, opting for a sharded database is recommended. Additionally, incorporating a regional cache can further enhance performance. From c26e7107915ef0579cb83f6fb5691aaff9b89357 Mon Sep 17 00:00:00 2001 From: conico974 Date: Fri, 21 Mar 2025 17:56:02 +0100 Subject: [PATCH 4/4] Update for #486 --- pages/cloudflare/caching.mdx | 6 ------ 1 file changed, 6 deletions(-) diff --git a/pages/cloudflare/caching.mdx b/pages/cloudflare/caching.mdx index 32d72a0..b4f3ee0 100644 --- a/pages/cloudflare/caching.mdx +++ b/pages/cloudflare/caching.mdx @@ -129,12 +129,6 @@ The D1 tag cache requires 1 table that tracks On-Demand revalidation times. The default table name is `revalidations` and can be configured by setting the `NEXT_CACHE_D1_REVALIDATIONS_TABLE` environment variable to a string. -Wrangler can be used to create a table with it's [execute](https://developers.cloudflare.com/d1/wrangler-commands/#d1-execute) option. Ensure that you create a table for both your local dev database and your remote database. - -```sh -wrangler d1 execute NEXT_CACHE_D1 --command "CREATE TABLE IF NOT EXISTS revalidations (tag TEXT NOT NULL, revalidatedAt INTEGER NOT NULL, UNIQUE(tag) ON CONFLICT REPLACE)" -``` - ##### 3. Configure the cache In your project's OpenNext config, enable the KV cache and set up a queue (see above). The queue will send a revalidation request to a page when needed, but it will not dedupe requests.