Skip to content

Latest commit

 

History

History
186 lines (138 loc) · 7.5 KB

File metadata and controls

186 lines (138 loc) · 7.5 KB

import { SITE } from "../../config"; import { Callout } from "nextra/components";

Caching

@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.

How to enable caching

@opennextjs/cloudflare supports multiple caching mechanisms through a project's OpenNext configuration.

Incremental Static Regeneration (ISR)

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.

1. Create a KV namespace
npx wrangler@latest kv namespace create <YOUR_NAMESPACE_NAME>
2. Add the KV namespace and Service Binding to your Worker

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.

// wrangler.jsonc
{
  // ...
  "kv_namespaces": [
    {
      "binding": "NEXT_CACHE_WORKERS_KV",
      "id": "<BINDING_ID>",
    },
  ],
  "services": [
    {
      "binding": "NEXT_CACHE_REVALIDATION_WORKER",
      "service": "<WORKER_NAME>",
    },
  ],
}

3. Configure the cache

In your project's OpenNext config, enable the KV cache and set up a queue.

The Durable Object Queue will send revalidation requests to a page when needed, and offers support for de-duplicating requests. By default there will be a maximum of 10 instance of the Durables Object Queue and they can each process up to 5 requests in parallel.(For up to 50 ISR revalidations in parallel)

// open-next.config.ts
import { defineCloudflareConfig } from "@opennextjs/cloudflare";
import kvIncrementalCache from "@opennextjs/cloudflare/kv-cache";
import doQueue from "@opennextjs/cloudflare/durable-queue";

export default defineCloudflareConfig({
  incrementalCache: kvIncrementalCache,
  queue: doQueue,
});

You will also need to add some binding to your wrangler.jsonc file.

"durable_objects": {
    "bindings": [
      {
        "name": "NEXT_CACHE_REVALIDATION_DURABLE_OBJECT",
        "class_name": "DurableObjectQueueHandler"
      }
    ]
  },
  "migrations": [
    {
      "tag": "v1",
      "new_sqlite_classes": ["DurableObjectQueueHandler"]
    }
  ],

You can customize the behaviors of the queue with environment variables:

  • The max number of durable workers that can be created (MAX_REVALIDATE_CONCURRENCY)
  • The max number of revalidations that can be processed by an instance of durable worker at the same time (MAX_REVALIDATION_BY_DURABLE_OBJECT)
  • The max time in milliseconds that a revalidation can take before being considered as failed (REVALIDATION_TIMEOUT_MS)
  • The amount of time after which a revalidation will be attempted again if it failed. If it fails again it will exponentially back off until it reaches the max retry interval (REVALIDATION_RETRY_INTERVAL_MS)
  • The maximum number of attempts that can be made to revalidate a path (MAX_REVALIDATION_ATTEMPTS)
There is 2 additional modes that you can use for the queue `direct` and the memory queue
  • The memory queue will dedupe request but only on a per isolate basis. It is not fully suitable for production deployments, you can use it at your own risk!

  • The direct mode for the queue is intended for debugging purposes and is not recommended for use in production. It only works in preview mode (i.e. wrangler dev)

On-Demand Revalidation

The tag revalidation mechanism uses a Cloudflare D1 database 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.
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 <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>",
    },
  ],
}
2. Create tables for tag revalidations

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)"
3. 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.

// 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,
});
4. Initialise the cache during deployments

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.