diff --git a/.changeset/pink-dodos-decide.md b/.changeset/pink-dodos-decide.md new file mode 100644 index 00000000..9b2148ad --- /dev/null +++ b/.changeset/pink-dodos-decide.md @@ -0,0 +1,5 @@ +--- +"@opennextjs/cloudflare": patch +--- + +perf: skip lazy update on cache hit when cache purge is enabled diff --git a/packages/cloudflare/src/api/overrides/incremental-cache/regional-cache.ts b/packages/cloudflare/src/api/overrides/incremental-cache/regional-cache.ts index 8ccd4f02..d2be28ab 100644 --- a/packages/cloudflare/src/api/overrides/incremental-cache/regional-cache.ts +++ b/packages/cloudflare/src/api/overrides/incremental-cache/regional-cache.ts @@ -35,14 +35,16 @@ type Options = { * Whether the regional cache entry should be updated in the background or not when it experiences * a cache hit. * - * @default `false` for the `short-lived` mode, and `true` for the `long-lived` mode. + * @default `true` in `long-lived` mode when cache purge is not used, `false` otherwise. */ 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. + * handled faster, + * + * Note: When this is enabled, make sure that the cache gets purged + * either by enabling the auto cache purging feature or manually. * * @default `true` if the auto cache purging is enabled, `false` otherwise. */ @@ -56,7 +58,16 @@ interface PutToCacheInput { } /** - * Wrapper adding a regional cache on an `IncrementalCache` implementation + * Wrapper adding a regional cache on an `IncrementalCache` implementation. + * + * Using a the `RegionalCache` does not directly improves the performance much. + * However it allows bypassing the tag cache (see `bypassTagCacheOnCacheHit`) on hits. + * That's where bigger perf gain happens. + * + * We recommend using cache purge. + * When cache purge is not enabled, there is a possibility that the Cache API (local to a Data Center) + * is out of sync with the cache store (i.e. R2). That's why when cache purge is not enabled the Cache + * API is refreshed from the cache store on cache hits (for the long-lived mode). */ class RegionalCache implements IncrementalCache { public name: string; @@ -71,7 +82,8 @@ class RegionalCache implements IncrementalCache { throw new Error("The KV incremental cache does not need a regional cache."); } this.name = this.store.name; - this.opts.shouldLazilyUpdateOnCacheHit ??= this.opts.mode === "long-lived"; + this.opts.shouldLazilyUpdateOnCacheHit ??= + this.opts.mode === "long-lived" && !this.#hasAutomaticCachePurging; } get #bypassTagCacheOnCacheHit(): boolean { @@ -103,7 +115,8 @@ class RegionalCache implements IncrementalCache { if (cachedResponse) { debugCache("Get - cached response"); - // Re-fetch from the store and update the regional cache in the background + // Re-fetch from the store and update the regional cache in the background. + // Note: this is only useful when the Cache API is not purged automatically. if (this.opts.shouldLazilyUpdateOnCacheHit) { getCloudflareContext().ctx.waitUntil( this.store.get(key, cacheType).then(async (rawEntry) => {