← Back

Caching with use cache

Opt-in caching with "use cache", revalidateTag + refresh() for invalidation.

PublishedMarch 5, 2026209 words
Edit

The "use cache" Directive

Next.js 16 introduces "use cache" for fine-grained caching. With cacheComponents: true, data fetching is dynamic by default—you opt into caching explicitly.

Basic Usage

From data/queries/post-queries.ts:

import { cache } from 'react'; import { cacheTag } from 'next/cache'; export const getPublishedPosts = cache(async () => { 'use cache'; cacheTag('posts'); return await prisma.post.findMany({ where: { published: true }, }); });
import { cache } from 'react'; import { cacheTag } from 'next/cache'; export const getPublishedPosts = cache(async () => { 'use cache';

Cache Invalidation with revalidateTag + refresh

In Server Actions, use revalidateTag with a profile plus refresh() for immediate UI updates:

import { refresh, revalidateTag } from 'next/cache'; export async function createPost(formData: FormData) { await prisma.post.create({ data })

Why Both?

| Function | Purpose | |----------|---------| | revalidateTag(tag, 'max') | Marks cache as stale, background revalidation | | refresh() | Forces client router re-render immediately |

The combination ensures the current user sees updates instantly while other users get stale-while-revalidate behavior.

Granular Tags

Tag individual items separately:

export const getPublishedPostBySlug = cache(async (slug: string) => { 'use cache'; cacheTag(`post-${slug}`); return

When updating a post, invalidate both its specific tag and the list tag.

cacheTag
(
'posts'
)
;
return
await
prisma
.
post
.
findMany
(
{
where
:
{
published
:
true
}
,
}
)
;
}
)
;
;
revalidateTag
(
'posts'
,
'max'
)
;
// Stale-while-revalidate for other users
refresh
(
)
;
// Immediate refresh for the current user
}
import { refresh, revalidateTag } from 'next/cache'; export async function createPost(formData: FormData) { await prisma.post.create({ data }); revalidateTag('posts', 'max'); // Stale-while-revalidate for other users refresh(); // Immediate refresh for the current user }
await
prisma
.
post
.
findUnique
(
{
where
:
{
slug
}
}
)
;
}
)
;
export const getPublishedPostBySlug = cache(async (slug: string) => { 'use cache'; cacheTag(`post-${slug}`); return await prisma.post.findUnique({ where: { slug } }); });