Cache expensive database queries
Repeated database reads
Next.js 16+ · Function
unstable_cache wraps an asynchronous operation so its result can be reused across requests. In Next.js 16, it has been replaced by the use cache directive for new code.
Call unstable_cache with an asynchronous function, globally identifying key parts, and optional revalidation settings. The returned function produces a Promise: a cache miss runs the wrapped function, stores its result, and returns it; later calls can reuse that result.
unstable_cache(fetchData, keyParts, options?)| Name | Type | Description |
|---|---|---|
fetchData | () => Promise<any> | Asynchronous function whose result should be cached; it must return a Promise. |
keyParts | string[] | Array of globally identifying values used to construct the cache key. |
options | { tags?: string[]; revalidate?: number } | Optional cache controls, including tags and revalidation time in seconds. |
A function that returns a Promise resolving to cached data; on a miss, it invokes the supplied function, caches the result, and returns it.
import { unstable_cache } from 'next/cache'
const getCachedUser = unstable_cache(
async (id: string) => fetch(`https://api.example.com/users/${id}`).then((r) => r.json()),
['user'],
{ revalidate: 3600, tags: ['user'] }
)
export async function getUser(id: string) {
return getCachedUser(id)
}Wrap an asynchronous data function to cache its result; calls with the same arguments can reuse the stored value.
Repeated database reads
Time-sensitive data
Group invalidation
It returns a new function that resolves to cached data. On a miss, the supplied asynchronous function runs, and its result is cached and returned.
Follow-up: How can the cache be invalidated selectively? Supply tags in the options and invalidate them with revalidateTag.
The key consists of the provided key parts together with the arguments passed to the returned function. Key parts should identify the cache entry globally.
Follow-up: Why should request-specific values be arguments? The arguments participate in the cache key, preventing unrelated requests from sharing one result.
The options object can define tags for invalidation and revalidate for time-based revalidation in seconds. These settings control how cached entries are refreshed or invalidated.
Follow-up: What should new Next.js 16 code use instead? Prefer Cache Components and the use cache directive, which replaces this API.
use cachecacheLifecacheTagrevalidateTagfetch