Movatterモバイル変換


[0]ホーム

URL:


Skip to content
Important
Security Advisory: React2Shell & two new vulnerabilities
Find out more

cacheLife

Last updated October 31, 2025

ThecacheLife function is used to set the cache lifetime of a function or component. It should be used alongside theuse cache directive, and within the scope of the function or component.

Usage

Basic setup

To usecacheLife, first enable thecacheComponents flag in yournext.config.js file:

next.config.ts
importtype { NextConfig }from'next'constnextConfig:NextConfig= {  cacheComponents:true,}exportdefault nextConfig

cacheLife requires theuse cache directive, which must be placed at the file level or at the top of an async function or component.

Good to know:

  • If used,cacheLife should be placed within the function whose output is being cached, even when theuse cache directive is at file level
  • Only onecacheLife call should execute per function invocation. You can callcacheLife in different control flow branches, but ensure only one executes per run. See theconditional cache lifetimes example

Using preset profiles

Next.js provides preset cache profiles that cover common caching needs. Each profile balances three factors:

  • How long users see cached content without checking for updates (client-side)
  • How often fresh content is generated on the server
  • When old content expires completely

Choose a profile based on how frequently your content changes:

  • seconds - Real-time data (stock prices, live scores)
  • minutes - Frequently updated (social feeds, news)
  • hours - Multiple daily updates (product inventory, weather)
  • days - Daily updates (blog posts, articles)
  • weeks - Weekly updates (podcasts, newsletters)
  • max - Rarely changes (legal pages, archived content)

ImportcacheLife and pass a profile name:

app/blog/page.tsx
'use cache'import { cacheLife }from'next/cache'exportdefaultasyncfunctionBlogPage() {cacheLife('days')// Blog content updated dailyconstposts=awaitgetBlogPosts()return <div>{/* render posts */}</div>}

The profile name tells Next.js how to cache the entire function's output. If you don't callcacheLife, thedefault profile is used. Seepreset cache profiles for timing details.

Reference

Cache profile properties

Cache profiles control caching behavior through three timing properties:

  • stale: How long the client can use cached data without checking the server
  • revalidate: After this time, the next request will trigger a background refresh
  • expire: After this time with no requests, the next one waits for fresh content

stale

Client-side: How long the client can use cached data without checking the server.

During this time, the client-side router displays cached content immediately without any network request. After this period expires, the router must check with the server on the next navigation or request. This provides instant page loads from the client cache, but data may be outdated.

cacheLife({ stale:300 })// 5 minutes

revalidate

How often the server regenerates cached content in the background.

  • When a request arrives after this period, the server:
    1. Serves the cached version immediately (if available)
    2. Regenerates content in the background
    3. Updates the cache with fresh content
  • Similar toIncremental Static Regeneration (ISR)
cacheLife({ revalidate:900 })// 15 minutes

expire

Maximum time before the server must regenerate cached content.

  • After this period with no traffic, the server regenerates content synchronously on the next request
  • When you set bothrevalidate andexpire,expire must be longer thanrevalidate. Next.js validates this and raises an error for invalid configurations.
cacheLife({ expire:3600 })// 1 hour

Preset cache profiles

If you don't specify a profile, Next.js uses thedefault profile. We recommend explicitly setting a profile to make caching behavior clear.

ProfileUse Casestalerevalidateexpire
defaultStandard content5 minutes15 minutes1 year
secondsReal-time data30 seconds1 second1 minute
minutesFrequently updated content5 minutes1 minute1 hour
hoursContent updated multiple times per day5 minutes1 hour1 day
daysContent updated daily5 minutes1 day1 week
weeksContent updated weekly5 minutes1 week30 days
maxStable content that rarely changes5 minutes30 days1 year

Custom cache profiles

Define reusable cache profiles in yournext.config.ts file:

next.config.ts
importtype { NextConfig }from'next'constnextConfig:NextConfig= {  cacheComponents:true,  cacheLife: {    biweekly: {      stale:60*60*24*14,// 14 days      revalidate:60*60*24,// 1 day      expire:60*60*24*14,// 14 days    },  },}exportdefault nextConfig

The example above caches for 14 days, checks for updates daily, and expires the cache after 14 days. You can then reference this profile throughout your application by its name:

app/page.tsx
'use cache'import { cacheLife }from'next/cache'exportdefaultasyncfunctionPage() {cacheLife('biweekly')return <div>Page</div>}

Overriding the default cache profiles

While the default cache profiles provide a useful way to think about how fresh or stale any given part of cacheable output can be, you may prefer different named profiles to better align with your applications caching strategies.

You can override the default named cache profiles by creating a new configuration with the same name as the defaults.

The example below shows how to override the default"days" cache profile:

next.config.ts
constnextConfig= {  cacheComponents:true,  cacheLife: {// Override the 'days' profile    days: {      stale:3600,// 1 hour      revalidate:900,// 15 minutes      expire:86400,// 1 day    },  },}exportdefault nextConfig

Inline cache profiles

For one-off cases, pass a profile object directly tocacheLife:

app/page.tsx
'use cache'import { cacheLife }from'next/cache'exportdefaultasyncfunctionPage() {cacheLife({    stale:3600,    revalidate:900,    expire:86400,  })return <div>Page</div>}

Inline profiles apply only to the specific function or component. For reusable configurations, define custom profiles innext.config.ts.

UsingcacheLife({}) with an empty object applies thedefault profile values.

Client router cache behavior

Thestale property controls the client-side router cache, not theCache-Control header:

  • The server sends the stale time via thex-nextjs-stale-time response header
  • The client router uses this value to determine when to revalidate
  • Minimum of 30 seconds is enforced to ensure prefetched links remain usable

This 30-second minimum prevents prefetched data from expiring before users can click on links. It only applies to time-based expiration.

When you call revalidation functions from a Server Action (revalidateTag,revalidatePath,updateTag, orrefresh), the entire client cache is immediately cleared, bypassing the stale time.

Good to know: Thestale property incacheLife differs fromstaleTimes. WhilestaleTimes is a global setting affecting all routes,cacheLife allows per-function or per-route configuration. UpdatingstaleTimes.static also updates thestale value of thedefault cache profile.

Examples

Using preset profiles

The simplest way to configure caching is using preset profiles. Choose one that matches your content's update pattern:

app/blog/[slug]/page.tsx
import { cacheLife }from'next/cache'exportdefaultasyncfunctionBlogPost() {'use cache'cacheLife('days')// Blog posts updated dailyconstpost=awaitfetchBlogPost()return <article>{post.content}</article>}
app/products/[id]/page.tsx
import { cacheLife }from'next/cache'exportdefaultasyncfunctionProductPage() {'use cache'cacheLife('hours')// Product data updated multiple times per dayconstproduct=awaitfetchProduct()return <div>{product.name}</div>}

Custom profiles for specific needs

Define custom profiles when preset options don't match your requirements:

next.config.ts
importtype { NextConfig }from'next'constnextConfig:NextConfig= {  cacheComponents:true,  cacheLife: {    editorial: {      stale:600,// 10 minutes      revalidate:3600,// 1 hour      expire:86400,// 1 day    },    marketing: {      stale:300,// 5 minutes      revalidate:1800,// 30 minutes      expire:43200,// 12 hours    },  },}exportdefault nextConfig

Then use these profiles throughout your application:

app/editorial/page.tsx
import { cacheLife }from'next/cache'exportdefaultasyncfunctionEditorialPage() {'use cache'cacheLife('editorial')// ...}

Inline profiles for unique cases

Use inline profiles when a specific function needs one-off caching behavior:

app/api/limited-offer/route.ts
import { cacheLife }from'next/cache'import { getDb }from'@lib/db'asyncfunctiongetLimitedOffer() {'use cache'cacheLife({    stale:60,// 1 minute    revalidate:300,// 5 minutes    expire:3600,// 1 hour  })constoffer=awaitgetDb().offer.findFirst({    where: { type:'limited' },    orderBy: { created_at:'desc' },  })return offer}exportasyncfunctionGET() {constoffer=awaitgetLimitedOffer()returnResponse.json(offer)}

Caching individual functions

Apply caching to utility functions for granular control:

lib/api.ts
import { cacheLife }from'next/cache'exportasyncfunctiongetSettings() {'use cache'cacheLife('max')// Settings rarely changereturnawaitfetchSettings()}
lib/stats.ts
import { cacheLife }from'next/cache'exportasyncfunctiongetRealtimeStats() {'use cache'cacheLife('seconds')// Stats update constantlyreturnawaitfetchStats()}

Nested caching behavior

When you nestuse cache directives (a cached function or component using another cached function or component), the outer cache's behavior depends on whether it has an explicitcacheLife.

With explicit outer cacheLife

The outer cache uses its own lifetime, regardless of inner cache lifetimes. When the outer cache hits, it returns the complete output including all nested data. An explicitcacheLife always takes precedence, whether it's longer or shorter than inner lifetimes.

app/dashboard/page.tsx
import { cacheLife }from'next/cache'import { Widget }from'./widget'exportdefaultasyncfunctionDashboard() {'use cache'cacheLife('hours')// Outer scope sets its own lifetimereturn (    <div>      <h1>Dashboard</h1>      <Widget /> {/* Inner scope has 'minutes' lifetime */}    </div>  )}

Without explicit outer cacheLife

If you don't callcacheLife in the outer cache, it uses thedefault profile (15 min revalidate). Inner caches with shorter lifetimes can reduce the outer cache'sdefault lifetime. Inner caches with longer lifetimes cannot extend it beyond the default.

app/dashboard/page.tsx
import { Widget }from'./widget'exportdefaultasyncfunctionDashboard() {'use cache'// No cacheLife call - uses default (15 min)// If Widget has 5 min → Dashboard becomes 5 min// If Widget has 1 hour → Dashboard stays 15 minreturn (    <div>      <h1>Dashboard</h1>      <Widget />    </div>  )}

It is recommended to specify an explicitcacheLife. With explicit lifetime values, you can inspect a cached function or component and immediately know its behavior without tracing through nested caches. Without explicit lifetime values, the behavior becomes dependent on inner cache lifetimes, making it harder to reason about.

Conditional cache lifetimes

You can callcacheLife conditionally in different code paths to set different cache durations based on your application logic:

lib/posts.ts
import { cacheLife, cacheTag }from'next/cache'asyncfunctiongetPostContent(slug:string) {'use cache'constpost=awaitfetchPost(slug)// Tag the cache entry for targeted revalidationcacheTag(`post-${slug}`)if (!post) {// Content may not be published yet or could be in draft// Cache briefly to reduce database loadcacheLife('minutes')returnnull  }// Published content can be cached longercacheLife('days')// Return only the necessary data to keep cache size minimalreturnpost.data}

This pattern is useful when different outcomes need different cache durations, for example, when an item is missing but is likely to be available later.

Using dynamic cache lifetimes from data

If you want to calculate cache lifetime at runtime, for example by reading it from the fetched data, use aninline cache profile object:

lib/posts.ts
import { cacheLife, cacheTag }from'next/cache'asyncfunctiongetPostContent(slug:string) {'use cache'constpost=awaitfetchPost(slug)cacheTag(`post-${slug}`)if (!post) {cacheLife('minutes')returnnull  }// Use cache timing from CMS data directly as an objectcacheLife({// Ensure post.revalidateSeconds is a number in seconds    revalidate:post.revalidateSeconds??3600,  })returnpost.data}

Related

View related API references.

Was this helpful?

supported.

[8]ページ先頭

©2009-2025 Movatter.jp