Skip to content

feat(cache): support custom configured cacheLife profiles - #3307

Open
NriotHrreion wants to merge 5 commits into
cloudflare:mainfrom
NriotHrreion:feature/custom-cache-life-policy
Open

NriotHrreion wants to merge 5 commits into
cloudflare:mainfrom
NriotHrreion:feature/custom-cache-life-policy

Conversation

@NriotHrreion

Copy link
Copy Markdown
Contributor

Overview

vinext previously ignored cacheLife profiles configured in next.config.* or inline vinext({ nextConfig }). As a result, calls such as cacheLife("blog") warned about an unknown profile, and configured overrides of built-in or default profiles had no effect.

This PR enables configured profiles across cacheLife(), unstable_cacheLife(), default caching and revalidateTag(tag, profile), with consistent lifetime settings in development, Node production and Cloudflare Workers production. Applications can define custom profiles, override built-in and default profiles, and let partial profiles inherit missing values from default. Existing built-in settings are preserved when no profiles are configured.

For example, an application can configure its profiles in next.config.ts:

export default {
  cacheLife: {
    default: { stale: 300, revalidate: 900, expire: 86400 },
    blog: { stale: 60, revalidate: 300, expire: 3600 },
    hours: { expire: 7200 },
  },
};

All durations are in seconds. Calling cacheLife("blog") applies the custom profile. Calling cacheLife("hours") uses the overridden expiration and inherits stale: 300 and revalidate: 900 from default. Cached functions without an explicit cacheLife() call use the configured default profile.

What changed

  • Builtin cache life profiles, such as default, seconds, minutes and etc., is extracted from packages/vinext/src/shims/cache-request-state.ts into packages/vinext/src/utils/cache-life-profiles.ts.
  • Added cacheLife?: Record<string, CacheLifeConfig> and experimental.cacheLife?: Record<string, CacheLifeConfig> (for compatibility) into NextConfig type. vinext reads config.cacheLife first, if not defined, then fallback to config.experimental.cacheLife and print a deprecation warning.
  • Support injecting cacheLife configuration via vite.config.ts.
  • In cacheLife(), pass the resolved cacheLifeProfiles into _setRequestScopedCacheLife():
export function cacheLife(profile: string | CacheLifeConfig): void {
  // ...

  _setRequestScopedCacheLife(
    typeof profile === "string"
      ? fillCacheLifeDefaults(resolvedConfig, cacheLifeProfiles.default)
      : resolvedConfig,
  );
}
  • Fill missing cacheLife fields from default after merging explicit durations, and preserve and replay lifetime metadata on private cache hits.
  • Updated readme and caching docs

Testing

  • pnpm test tests/cache-life-profiles.test.ts tests/cache-life-runtime.test.ts tests/cache-life-config.test.ts tests/cache-life-build.test.ts
  • pnpm test tests/next-config.test.ts tests/pages-router.test.ts tests/prerender-config.test.ts

Notes

This PR only supports configured runtime profiles. Typegen of cache-life.d.ts is not implemented.

Refs #3244

@pkg-pr-new

pkg-pr-new Bot commented Sep 17, 2026

Copy link
Copy Markdown

Open in StackBlitz

@vinext/cloudflare

npm i https://pkg.pr.new/@vinext/cloudflare@3307

create-vinext-app

npm i https://pkg.pr.new/create-vinext-app@3307

@vinext/types

npm i https://pkg.pr.new/@vinext/types@3307

vinext

npm i https://pkg.pr.new/vinext@3307

@cloudflare/workers-response-store

npm i https://pkg.pr.new/@cloudflare/workers-response-store@3307

commit: b27e7a6

@github-actions

Copy link
Copy Markdown
Contributor

Performance benchmarks

Compared b27e7a6 against base 49b7fe0 using alternating same-runner rounds. Next.js was unchanged and skipped.

1 improved · 1 regressed · 4 within ±1.5%

Scenario Framework Baseline Current Change
Client bundle size (gzip) vinext 142.2 KB 142.2 KB ⚫ -0.0%
Client entry size (gzip) vinext 129.6 KB 129.6 KB ⚫ -0.0%
Dev server cold start vinext 2.49 s 2.44 s 🟢 -2.1%
Production build time vinext 2.75 s 2.80 s 🔴 +1.7%
RSC entry closure size (gzip) vinext 121.0 KB 121.2 KB ⚫ +0.1%
Server bundle size (gzip) vinext 211.0 KB 211.3 KB ⚫ +0.1%

View detailed results and traces

🟢 improvement · 🔴 regression · ⚫ change below 1.5% · paired base/head

@james-elicx

Copy link
Copy Markdown
Member

/bigbonk review for issues

@ask-bonk

ask-bonk Bot commented Sep 17, 2026

Copy link
Copy Markdown
Contributor

@james-elicx Bonk workflow was cancelled.

View workflow run · To retry, trigger Bonk again.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants