import { SITE } from "../../config"; import { Callout } from "nextra/components"; import { Tabs } from "nextra/components";
@opennextjs/cloudflare
supports caching.
Next.js primes the cache at build time. The build time values are serverd by the Workers Assets.
Workers KV is eventually consistent, which means that it can take up to 60 seconds for updates to be reflected globally, when using the default TTL of 60 seconds.@opennextjs/cloudflare
supports multiple caching mechanisms through a project's OpenNext configuration.
The ISR adapter for Cloudflare uses Workers KV as the cache for your Next.js app. Workers KV is fast and uses Cloudflare's Tiered Cache to increase cache hit rates. When you write cached data to Workers KV, you write to storage that can be read by any Cloudflare location. This means your app can fetch data, cache it in KV, and then subsequent requests anywhere around the world can read from this cache. Pricing information can be found in the Cloudflare docs.
npx wrangler@latest kv namespace create <YOUR_NAMESPACE_NAME>
The binding name used in your app's worker is NEXT_CACHE_WORKERS_KV
. The service binding should be a self reference to your worker where <WORKER_NAME>
is the name in your wrangler configuration file.
In your project's OpenNext config, enable the KV cache and set up a queue.
The memory queue will send revalidation requests to a page when needed, and offers support for de-duplicating requests on a per-isolate basis. There might still be duplicate requests under high traffic or across regions.
The memory queue provided by `@opennextjs/cloudflare` is not fully suitable for production deployments, you can use it at your own risk!// open-next.config.ts
import { defineCloudflareConfig } from "@opennextjs/cloudflare";
import kvIncrementalCache from "@opennextjs/cloudflare/kv-cache";
import memoryQueue from "@opennextjs/cloudflare/memory-queue";
export default defineCloudflareConfig({
incrementalCache: kvIncrementalCache,
queue: memoryQueue,
});
The tag revalidation mechanism can use either a Cloudflare D1 database or 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.
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 your app doesn't to use `revalidateTag` nor `revalidatePath`.There are 3 different options to choose from for the tag cache: 'd1NextTagCache', ShardedTagCache
and d1TagCache
.
Which one to choose should be based on two key factors:
- Expected Load: Consider the volume of traffic or data you anticipate.
- 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.
<Tabs items={["D1NextTagCache", "ShardedTagCache", "D1TagCache"]}> <Tabs.Tab>
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 <WORKER_NAME>
is the name in your wrangler configuration file.
// wrangler.jsonc
{
// ...
"d1_databases": [
{
"binding": "NEXT_CACHE_D1",
"database_id": "<DATABASE_ID>",
"database_name": "<DATABASE_NAME>",
},
],
"services": [
{
"binding": "NEXT_CACHE_REVALIDATION_WORKER",
"service": "<WORKER_NAME>",
},
],
}
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.
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.
// 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,
});
</Tabs.Tab>
<Tabs.Tab>
The service binding should be a self reference to your worker where <WORKER_NAME>
is the name in your wrangler configuration file.
// 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": "<WORKER_NAME>",
},
],
}
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.
// 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.
</Tabs.Tab>
<Tabs.Tab>
The `d1TagCache` is not recommended for production use, as it does not scale well with the number of tags.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 <WORKER_NAME>
is the name in your wrangler configuration file.
// wrangler.jsonc
{
// ...
"d1_databases": [
{
"binding": "NEXT_CACHE_D1",
"database_id": "<DATABASE_ID>",
"database_name": "<DATABASE_NAME>",
},
],
"services": [
{
"binding": "NEXT_CACHE_REVALIDATION_WORKER",
"service": "<WORKER_NAME>",
},
],
}
The D1 tag cache requires two tables; one that keeps a record of the tag/path mappings, and another that tracks revalidation times.
For the tag mappings, the default table name is tags
, and can be configured by setting the NEXT_CACHE_D1_TAGS_TABLE
environment variable to a string.
For the 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 option. Ensure that you create a table for both your local dev database and your remote database.
wrangler d1 execute NEXT_CACHE_D1 --command "CREATE TABLE IF NOT EXISTS tags (tag TEXT NOT NULL, path TEXT NOT NULL, UNIQUE(tag, path) ON CONFLICT REPLACE)"
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)"
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.
// open-next.config.ts
import { defineCloudflareConfig } from "@opennextjs/cloudflare";
import kvIncrementalCache from "@opennextjs/cloudflare/kv-cache";
import d1TagCache from "@opennextjs/cloudflare/d1-tag-cache";
import memoryQueue from "@opennextjs/cloudflare/memory-queue";
export default defineCloudflareConfig({
incrementalCache: kvIncrementalCache,
tagCache: d1TagCache,
queue: memoryQueue,
});
In order for the cache to be properly initialised with the build-time revalidation data, you need to setup a command that runs as part of your deploy step.
OpenNext will generate an SQL file during the build that can be used to setup your D1 database.
wrangler d1 execute NEXT_CACHE_D1 --file .open-next/cloudflare/cache-assets-manifest.sql
This should be run as part of each deployment to ensure that the cache is being populated with each build's initial revalidation data.
</Tabs.Tab>