Skip to content
26 changes: 26 additions & 0 deletions .changeset/lovely-gifts-cough.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
---
"@opennextjs/cloudflare": minor
---

Add option for regional cache to skip tagCache on cache hits

When the tag regional cache finds a value in the incremental cache, checking such value in the tagCache can be skipped, this helps reducing response times at the tradeoff that the user needs to either use the automatic cache purging or manually purge the cache when appropriate. For this the `bypassTagCacheOnCacheHit` option is being added to the `RegionalCache` class.

Example:

```js
import { defineCloudflareConfig } from "@opennextjs/cloudflare";
import d1NextTagCache from "@opennextjs/cloudflare/overrides/tag-cache/d1-next-tag-cache";
import memoryQueue from "@opennextjs/cloudflare/overrides/queue/memory-queue";
import r2IncrementalCache from "@opennextjs/cloudflare/overrides/incremental-cache/r2-incremental-cache";
import { withRegionalCache } from "@opennextjs/cloudflare/overrides/incremental-cache/regional-cache";

export default defineCloudflareConfig({
incrementalCache: withRegionalCache(r2IncrementalCache, {
mode: "long-lived",
bypassTagCacheOnCacheHit: true,
}),
tagCache: d1NextTagCache,
queue: memoryQueue,
});
```
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,15 @@ type Options = {
* @default `false` for the `short-lived` mode, and `true` for the `long-lived` mode.
*/
shouldLazilyUpdateOnCacheHit?: boolean;

/**
* Whether on cache hits the tagCache should be skipped or not. Skipping the tagCache allows requests to be
* handled faster, the downside of this is that you need to make sure that the cache gets correctly purged
* either by enabling the auto cache purging feature or doing that manually.
*
* @default `true` if the auto cache purging is enabled, `false` otherwise.
*/
bypassTagCacheOnCacheHit?: boolean;
};

interface PutToCacheInput {
Expand Down Expand Up @@ -65,6 +74,17 @@ class RegionalCache implements IncrementalCache {
this.opts.shouldLazilyUpdateOnCacheHit ??= this.opts.mode === "long-lived";
}

get #bypassTagCacheOnCacheHit(): boolean {
if (this.opts.bypassTagCacheOnCacheHit !== undefined) {
// If the bypassTagCacheOnCacheHit option is set we return that one
return this.opts.bypassTagCacheOnCacheHit;
}

// Otherwise we default to whether the automatic cache purging is enabled or not
const hasAutomaticCachePurging = !!getCloudflareContext().env.NEXT_CACHE_DO_PURGE;
return hasAutomaticCachePurging;
}

async get<CacheType extends CacheEntryType = "cache">(
key: string,
cacheType?: CacheType
Expand All @@ -91,7 +111,12 @@ class RegionalCache implements IncrementalCache {
);
}

return cachedResponse.json();
const responseJson: Record<string, unknown> = await cachedResponse.json();

return {
...responseJson,
shouldBypassTagCache: this.#bypassTagCacheOnCacheHit,
};
}

const rawEntry = await this.store.get(key, cacheType);
Expand Down