Back to list
HoangNguyen0403

nextjs-caching-architecture

by HoangNguyen0403

A collection of Agent Skills Standard and Best Practice for Programming Languages, Frameworks that help our AI Agent follow best practies on frameworks and programming laguages

111🍴 40📅 Jan 23, 2026

SKILL.md


name: Next.js Caching Architecture description: The 4 layers of caching (Memoization, Data Cache, Full Route, Router Cache). metadata: labels: [nextjs, caching, isr, revalidation] triggers: files: ['/page.tsx', '/layout.tsx', '**/action.ts'] keywords: [unstable_cache, revalidateTag, Router Cache, Data Cache]

Caching Architecture

Priority: P1 (HIGH)

Next.js has 4 distinct caching layers. Understanding them prevents stale data bugs.

The 4 Layers

LayerWhereDurationPurposeControl
1. Request MemoizationServerPer RequestDeduplicate same fetch() calls in one render pass.AbortController
2. Data CacheServerPersistentStore data across user requests.revalidateTag
3. Full Route CacheServerPersistentStore HTML/RSC payload. (Static Rendering).revalidatePath
4. Router CacheClientSession (< 5m)Navigating back/forward without server hit.router.refresh()

1. Request Memoization

  • Behavior: Calling getUser(1) in layout, page, and component only triggers 1 network call.

  • Key: Matches URL and Options exactly.

  • Non-Fetch: For DB calls/Prisma, use React cache() manually.

    import { cache } from 'react';
    const getItem = cache(async (id) => db.item.findUnique({ id }));
    

2. Data Cache (The "Server Persistence")

  • Default: fetch tracks cache indefinitely (force-cache).

  • Scaling:

    • Vercel: Shared globally via KV/Blob.
    • Self-Hosted: Stored in filesystem (Pod ephemeral storage). Critical: Must configure a shared cacheHandler (Redis) for multi-pod Kubernetes setups, otherwise pods have desynchronized caches.
  • Granular Control: Use unstable_cache for DB queries caching.

    import { unstable_cache } from 'next/cache';
    const getCachedUser = unstable_cache(
      async (id) => db.user.find(id),
      ['users-key'],
      { tags: ['users'], revalidate: 60 },
    );
    

3. Router Cache (The "Client Stale")

  • Problem: User updates a listing, navigates back, and sees old data.
  • Cause: Client-side Router Cache holds payload for 30s (dynamic) or 5m (static).
  • Fix: Call router.refresh() in a Client Component or revalidatePath() in a Server Action (which automatically invalidates Router Cache).

Strategies

  • Opt-Out (Real-Time):
    • Data: fetch(..., { cache: 'no-store' })
    • Route: export const dynamic = 'force-dynamic'
  • On-Demand (CMS/Admin):
    • Use revalidateTag('collection') for surgical updates. Better than revalidatePath (which nukes the whole URL).

Score

Total Score

85/100

Based on repository quality metrics

SKILL.md

SKILL.mdファイルが含まれている

+20
LICENSE

ライセンスが設定されている

+10
説明文

100文字以上の説明がある

+10
人気

GitHub Stars 100以上

+5
最近の活動

1ヶ月以内に更新

+10
フォーク

10回以上フォークされている

+5
Issue管理

オープンIssueが50未満

+5
言語

プログラミング言語が設定されている

+5
タグ

1つ以上のタグが設定されている

+5

Reviews

💬

Reviews coming soon