Next.js Data Fetching and Cache
Pack:
nextjsSource:nextjs/nextjs-data-fetching-and-cache/SKILL.mdUse this skill when the task is mostly about reading data in App Router or choosing the right cache and revalidation primitive.
- server-first data fetching with
fetch - request memoization and route cache behavior
use cache,unstable_cache, cache tags, and cache life decisionsrevalidatePath,revalidateTag, andupdateTaggenerateStaticParamsand static param generation- high-level static vs dynamic vs revalidated route decisions
Routing cues
Section titled “Routing cues”fetchin Server Components, request caching, revalidation, cache tags,unstable_cache,use cache, orgenerateStaticParams-> use this skill- mutation flow, form submission,
use server, or Route Handlers as the primary concern -> usenextjs-server-actions-and-route-handlers - streaming and runtime boundaries as the main concern -> use
nextjs-rendering-runtime-and-middleware
Default path
Section titled “Default path”- Read references/cache-and-revalidation-matrix.md first.
- Decide whether the data is public, tenant-scoped, or user-specific before applying any cache primitive.
- Prefer the smallest cache primitive that matches the invalidation needs.
- Start with normal App Router
fetchplus explicitnextcache options before reaching for lower-level cache helpers. - Route out if the task turns into mostly mutation semantics or runtime placement.
When to deviate
Section titled “When to deviate”- Use
unstable_cacheonly when plainfetchcaching does not model the access pattern cleanly. - Keep data fully dynamic when the response is personalized, auth-scoped, or otherwise unsafe to share.
- Reach for
generateStaticParamsonly when route params are truly known ahead of time and the route benefits from static generation. - Move to the server-actions skill when the invalidation story is attached to a mutation, not a read path.
Quick example
Section titled “Quick example”const posts = await fetch('https://api.example.com/posts', { next: { revalidate: 3600, tags: ['posts'] },}).then((res) => res.json())Guardrails
Section titled “Guardrails”- Do not apply public caching blindly to personalized or auth-scoped data.
- Prefer App Router cache primitives over legacy Pages Router data APIs.
- Treat
revalidatePathas route-oriented invalidation andrevalidateTag/updateTagas data-oriented invalidation. - Reach for
unstable_cacheonly when normalfetchcaching does not fit the access pattern. - Keep cache ownership obvious. Hidden invalidation paths age badly.
- caching user-specific or session-specific data as if it were public
- using
revalidatePathand tag invalidation interchangeably without a clear ownership model - introducing
unstable_cachefirst and only later asking whether normalfetchwould work - mixing read-path cache guidance with mutation orchestration in the same answer
Verification checklist
Section titled “Verification checklist”- the data scope is identified as public, tenant-scoped, or user-specific
- the chosen cache primitive matches the invalidation need
- route invalidation and data invalidation are not conflated
- personalized data is not accidentally cached as shared content
- the response routes to the mutation or runtime skill if the problem is no longer mainly about reads
Canonical APIs
Section titled “Canonical APIs”fetchgenerateStaticParamsrevalidatePathrevalidateTagupdateTagunstable_cacheuse cache
Maintenance
Section titled “Maintenance”- Snapshot date: 2026-04-03
- Package snapshot:
next@16.2.2 - Docs status snapshot: official App Router docs now center the cache model around Cache Components and
use cache, while legacy cache APIs remain documented for compatibility and migration