Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/pink-dodos-decide.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@opennextjs/cloudflare": patch
---

perf: skip lazy update on cache hit when cache purge is enabled
Original file line number Diff line number Diff line change
Expand Up @@ -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.
*/
Expand All @@ -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;
Expand All @@ -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 {
Expand Down Expand Up @@ -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) => {
Expand Down