`use cache` vs React `cache()` vs `unstable_cache` in Next.js

Three cache helpers with similar names and different jobs. Learn how use cache, React cache(), and unstable_cache differ in lifetime and persistence.

7 min read

Next.js has three cache helpers with overlapping names: use cache, React cache(), and unstable_cache. They differ in two ways that matter most: how long an entry lasts and whether a new deploy resets it.

HelperKindLifetimePersists across deploys
use cacheNext.js directivecacheLife profileNo
React cache()React functionOne server requestNo
unstable_cacheNext.js functionrevalidate secondsYes

use cache

The use cache directive is the Cache Components way to cache. It keeps a result across requests for as long as its cacheLife profile allows, and it is how cached output joins the static shell during prerendering.

typescripttypescript
// app/lib/posts.ts
import { cacheLife } from 'next/cache'
 
export async function getPosts() {
  'use cache'
  cacheLife('hours')
  const res = await fetch('https://api.example.com/posts')
  return res.json()
}

The entry is keyed partly by the build ID, so a fresh deploy starts with an empty cache. It runs on the server only and cannot read cookies or headers directly. See the use cache directive for its three placements.

React cache()

React cache() deduplicates calls within a single server request. It works in Server Components only, has no lifetime and no storage, so two components that call the same function with the same arguments run it once per request.

typescripttypescript
// app/lib/weather.ts
import { cache } from 'react'
 
export const getTemperature = cache(async (city: string) => {
  const res = await fetch(`https://api.example.com/weather/${city}`)
  return res.json()
})

This is the right tool for ORM and database calls, which automatic fetch memoization cannot see. It must be defined at module scope, not inside a component, or every render creates a fresh memoized function. Unlike the framework cache, it holds nothing after the request finishes.

unstable_cache

unstable_cache wraps an async function for the pre-Cache-Components model. Unlike use cache, its entries persist across requests and deployments.

typescripttypescript
// app/lib/posts.ts
import { unstable_cache } from 'next/cache'
 
export const getCachedPosts = unstable_cache(
  async () => {
    const res = await fetch('https://api.example.com/posts')
    return res.json()
  },
  ['posts'],
  { tags: ['posts'], revalidate: 3600 }
)

Next.js 16 recommends replacing it with use cache, and the function was never promoted past its unstable prefix. It remains the one to reach for when data must survive a deploy.

Which one to use

  • Use use cache for any new caching in a Cache Components app.
  • Use React cache() when you only need to deduplicate within one request.
  • Reach for unstable_cache only when data must persist across deploys.

For moving existing unstable_cache calls over, see migrating from unstable_cache. Mixing the three in one file is fine, but name the one you mean, because their lifetimes do not line up.

Common mistakes

  • Confusing React cache() with use cache. React cache() never persists, so wrapping it around a function does not cache across requests.
  • Defining React cache() inside a component, which creates a new memoized function on every render.
  • Reaching for unstable_cache in a Cache Components app, where use cache is the intended tool.
Rune AI

Rune AI

Key Insights

  • use cache caches across requests within a deploy.
  • React cache() deduplicates within one server request.
  • unstable_cache persists across deploys, and use cache replaces it.
  • Only use cache and cacheLife work inside Cache Components.
  • Choose by lifetime and whether a deploy must reset the cache.
RunePowered by Rune AI

Frequently Asked Questions

Does React cache() persist across requests?

No. React cache() only deduplicates calls within a single server request. It has no lifetime and no storage.

Which one survives a new deploy?

Only unstable_cache persists across deployments. use cache entries include the build ID in their key, so a new build starts with empty caches.

Conclusion

use cache is the current caching tool, React cache() deduplicates within one request, and unstable_cache persists across deploys, though Next.js 16 replaces it with use cache. Pick the narrowest one that fits the lifetime you actually need.