メインコンテンツにスキップ
株式会社ゼットリンカー - Next.js システム開発専門
Next.js

Next.js 16 の use cache を中小企業のフルスクラッチでどう使い分けるか

Conclusion

use cache はマスタ系に限定し、cacheLife と cacheTag で時間軸と業務イベントの両面から無効化する設計が現実的です。

Next.js 16 で導入された明示的キャッシュ(use cache / cacheLife / cacheTag)を、中小企業のフルスクラッチ業務システムでどう設計するか。3つの判断軸と落とし穴を実例で解説します。

7分で読めます
Next.jsNext.jsTypeScriptTypeScript中小企業AI駆動開発

Next.js 16 になって、キャッシュの考え方が大きく変わりました。これまでの「fetch がデフォルトでキャッシュされる」モデルから、「明示的に use cache と書いた箇所だけキャッシュする」モデルへの転換です。

この変化は、業務システムを受託で作っている私たちのような開発会社にとっては、むしろ歓迎すべき変更だと感じています。何がキャッシュされていて、何が毎回サーバーで実行されているのか、コードを見ただけで判断できるようになるからです。

一方で、中小企業向けのフルスクラッチで「どこに use cache を入れるべきか」「cacheLifecacheTag をどう使い分けるか」は、Next.js 公式ドキュメントを読んだだけでは判断しづらい部分でもあります。本記事では、私たちが社内・受託案件で運用している判断基準をまとめます。

Next.js 16 のキャッシュは「明示的オプトイン」になった

Next.js 16 では、ページ・レイアウト・API ルートのコードはすべて、デフォルトでリクエスト時に実行されます(Next.js 16 公式ブログ)。何かを「キャッシュしたい」と思った場合は、関数やコンポーネントの先頭に "use cache" を書いて、明示的にキャッシュ対象であることを宣言します。

// app/lib/products.ts
export async function getFeaturedProducts() {
  "use cache";
  const products = await db.product.findMany({
    where: { featured: true },
    orderBy: { updatedAt: "desc" },
  });
  return products;
}

このシンプルさが効いてきます。コードレビューで「ここはキャッシュされていますか?」という議論が、関数の先頭を見るだけで終わるようになりました。

どこに use cache を入れるか、3つの判断軸

私たちは、業務システムの設計時に次の3つの軸でキャッシュ対象を選びます。

軸1: 全ユーザー共通か、ユーザー個別か

全ユーザーで同じ結果を見せてよい関数は use cache の候補です。たとえば「公開中の商品一覧」「企業の問い合わせフォームに表示する選択肢マスタ」「公開記事のリスト」など。

逆にログインユーザーごとに結果が変わるもの、たとえば「自分の発注履歴」「自分の権限で見える顧客一覧」は、原則キャッシュしません。どうしてもキャッシュしたい場合は、後述の use cache: private を検討します。

軸2: 更新頻度がどのくらいか

1日に数回しか更新されないデータと、1分ごとに変わるデータでは、キャッシュ戦略がまったく違います。

  • 商品マスタ・カテゴリ一覧 → 1日数回 → cacheLife("hours")
  • 在庫数・受注ステータス → 数分単位 → cacheLife("minutes") or 都度更新
  • ダッシュボードの集計値 → 1日1回バッチ更新 → cacheLife("days")

軸3: 古いデータを見せてよいか

ECの商品説明であれば、数分古いキャッシュを見せても大きな問題にはなりません。一方、銀行の残高や予約システムの空き枠は、1秒でも古いデータを見せられないケースがあります。

「どれくらい古いデータならOKか」を業務側にヒアリングして決めるのが、いちばん確実です。

Next.js 16のuse cacheをどこに入れるか判断するための決定木図。共通データか個別データか、更新頻度はどれくらいか、古いデータを許容できるかの3つの軸から、cacheLifeで寿命を決めcacheTagで業務イベント起点に無効化する結論へとつながる流れを示す。

ここで一度お知らせ

15分のカジュアル相談

事例・要件未定でもOK/営業はしません/所要時間15分

カジュアルに相談する

cacheLife と cacheTag の使い分け

use cache と組み合わせて使う関数が2つあります。cacheLifecacheTag です。

cacheLife: 時間ベースの有効期限

cacheLife はキャッシュの寿命を決めるための関数です。Next.js が用意した "minutes" "hours" "days" "weeks" などのプロファイルを使うか、独自のプロファイルを定義できます。

import { cacheLife } from "next/cache";

export async function getCategoryList() {
  "use cache";
  cacheLife("hours");
  return await db.category.findMany({ where: { active: true } });
}

中小企業の業務システムでは、まずプリセットの "minutes" "hours" で十分なことが多いです。next.config.js で独自プロファイルを定義する必要が出てくるのは、独特の更新頻度を持つデータ(毎週月曜の朝に更新される、など)に当たったときです。

cacheTag: 業務イベント起点で無効化する

cacheTag は、キャッシュにタグを付けて、後から revalidateTag で明示的に無効化できる仕組みです。

import { cacheTag } from "next/cache";

export async function getProductDetail(productId: string) {
  "use cache";
  cacheTag(`product-${productId}`, "products");
  return await db.product.findUnique({ where: { id: productId } });
}

商品マスタを更新した瞬間に、関連する全キャッシュを破棄したい場合は、Server Action からタグ単位で破棄します。

"use server";
import { revalidateTag } from "next/cache";

export async function updateProduct(productId: string, data: ProductInput) {
  await db.product.update({ where: { id: productId }, data });
  // この商品だけ破棄
  revalidateTag(`product-${productId}`);
  // 一覧系も破棄
  revalidateTag("products");
}

私たちの実務感覚では、cacheLife だけで足りるケースは少なく、ほとんどの業務データには cacheTag も併用します。「業務側のアクションでデータが更新された瞬間に、即座にUIに反映したい」というニーズが必ずあるからです。

use cache の中で cookies / headers は読めない

ハマりやすいポイントとして、use cache で囲んだ関数の中では cookies() headers() searchParams といったリクエスト時のAPIを直接呼べません(Next.js 公式 use cache ドキュメント)。

これらの値はキャッシュ関数の外で取得し、引数として渡す設計に変えます。

// ✗ NG: use cache 内で cookies を呼ぼうとしている
export async function getMyOrders() {
  "use cache";
  const cookieStore = await cookies();
  const userId = cookieStore.get("userId")?.value;
  return await db.order.findMany({ where: { userId } });
}

// ○ OK: 引数として userId を受け取る
async function getOrdersByUser(userId: string) {
  "use cache";
  cacheTag(`orders-${userId}`);
  return await db.order.findMany({ where: { userId } });
}

// 呼び出し側(Server Component)で cookies を読んで渡す
export async function MyOrdersPage() {
  const cookieStore = await cookies();
  const userId = cookieStore.get("userId")?.value;
  if (!userId) redirect("/login");
  const orders = await getOrdersByUser(userId);
  return <OrderList orders={orders} />;
}

「ユーザー個別データはキャッシュしない」という大原則と組み合わせると、use cache を入れる位置に迷うことがそもそも減ります。

中小企業向けの現実的な初期設計

新規プロジェクトを立ち上げるとき、私たちは次の方針でスタートしています。

  1. デフォルトはキャッシュなしuse cache を書いた関数だけがキャッシュ対象
  2. マスタ系(商品・カテゴリ・顧客区分など)は cacheLife("hours") + cacheTag
  3. ダッシュボードの集計値は cacheLife("days") + 夜間バッチで revalidateTag
  4. 個人別データは原則キャッシュしない。必要なら呼び出し側で memoize
  5. 本番リリース後、Vercel のメトリクスを見て、キャッシュヒット率の低い関数から見直す

最初から完璧なキャッシュ設計を目指すと、設計コストが膨らみます。中小企業の予算感では「まずキャッシュなしで動くものを作って、ボトルネックが見えてから足す」アプローチのほうが合っていることが多いです。

SaaS から移行するときに効いてくる

WordPress や既存 SaaS から自社専用システムに切り替える案件で、Next.js 16 のキャッシュ設計の良さを実感する場面があります。SaaS では「裏側のキャッシュ挙動が見えない」「無効化のタイミングを制御できない」ことが運用上のストレスになっていることが多いのですが、フルスクラッチで作れば、業務イベント起点で正確に無効化する仕組みを自分たちで握れます。

このあたりの判断軸については、受発注管理を SaaS から Next.js フルスクラッチに切り替える判断基準中小企業の「SaaS疲れ」を解消する|Next.js フルスクラッチという選択肢も併せて参考になると思います。社内ダッシュボード設計の観点は散らばった社内データを1枚のダッシュボードに集約する|Next.js × Firebaseの設計、AI連携を組み合わせる場合は【2026年版】Next.js × AIエージェントで業務を自動化する実務ガイドが参考になります。

まとめ

Next.js 16 の use cache は、中小企業向けの業務システムでも十分に活用できる設計に進化しています。「キャッシュ対象を明示する」「cacheLife で寿命、cacheTag で業務イベント無効化」「個人別データはキャッシュしない」という3つを押さえれば、運用しやすいキャッシュ設計に近づきます。

設計時のチェックリスト(PDF版)や、移行コストの見積もり方法については個別にお渡ししています。具体の現場に当てはめて議論したい方は、15分の壁打ちからご相談を受け付けています。

キャッシュ設計とあわせて、Next.js 開発そのもののパフォーマンスを底上げしたい方には、高速レンダリングを極めるNext.js専門開発チームのパフォーマンスチューニング術【2026年版】Next.js 16の新機能とパフォーマンス最適化Next.jsシステム開発におけるパフォーマンス最適化の実践的アプローチもあわせてご覧ください。use cache だけでなく、レンダリング全体の最適化まで含めて中小企業のフルスクラッチ案件に落とし込む視点が整理できるはずです。

本記事は Next.js 16.x 時点の情報です

最終更新:2026年5月6日

Share this article

15分のカジュアル相談

事例・要件未定でもOK/営業はしません/所要時間15分

カジュアルに相談する

次に読む記事

ALL ARTICLES →

プライバシーポリシー

株式会社ゼットリンカー(以下、「当社」といいます。)は、お客様の個人情報の重要性を認識し、 その保護の徹底を図るため、以下のプライバシーポリシー(以下、「本ポリシー」といいます。)を定めます。

1. 個人情報の定義

本ポリシーにおいて「個人情報」とは、生存する個人に関する情報であって、 当該情報に含まれる氏名、生年月日その他の記述等により特定の個人を識別することができるもの、 及び他の情報と容易に照合することができ、それにより特定の個人を識別することができることとなるものを指します。

2. 個人情報の収集

当社は、お客様が当社のサービスをご利用になる際、お客様の個人情報を収集することがあります。収集する個人情報は以下の通りです:

  • 氏名
  • メールアドレス
  • 電話番号
  • 会社名・組織名
  • 住所
  • その他当社が定める入力フォームにお客様が入力する情報

3. 個人情報の利用目的

当社は、お客様からご提供いただいた個人情報を、以下の目的で利用します:

  • お客様への連絡やサービスの提供
  • お客様からのお問い合わせへの対応
  • 当社サービスの改善や新サービスの開発
  • メールマガジンの配信(お客様の同意がある場合)
  • 契約や法令等に基づく権利の行使や義務の履行
  • その他、上記利用目的に付随する目的

4. 個人情報の第三者提供

当社は、以下の場合を除き、お客様の同意なく個人情報を第三者に提供することはありません:

  • 法令に基づく場合
  • 人の生命、身体または財産の保護のために必要がある場合であって、本人の同意を得ることが困難である場合
  • 公衆衛生の向上または児童の健全な育成の推進のために特に必要がある場合
  • 国の機関もしくは地方公共団体またはその委託を受けた者が法令の定める事務を遂行することに対して協力する必要がある場合

5. 個人情報の管理

当社は、お客様の個人情報を正確かつ最新の状態に保ち、個人情報への不正アクセス、 個人情報の紛失、破損、改ざん及び漏洩などを防止するため、 セキュリティシステムの維持・管理体制の整備等の必要な措置を講じ、安全対策を実施し個人情報の厳重な管理を行います。

6. 個人情報の開示・訂正・削除

お客様は、当社に対してご自身の個人情報の開示を求めることができます。 また、開示の結果、個人情報の内容が事実でないことが判明した場合には、 速やかに訂正または削除に応じます。

7. 導入事例の公開について

当社は、お客様から依頼いただいたプロジェクトを導入事例として記事にさせていただく場合があります。導入事例として公開する場合は、以下の点に配慮いたします:

  • 機密情報や個人情報は公開いたしません
  • 社名を公開する場合は、公開内容について事前にお客様に確認いただきます
  • 社名を非公開とする場合でも、お客様のご要望に応じて公開内容を確認いただくことが可能です

8. Cookie(クッキー)の使用について

当社のウェブサイトでは、お客様により良いサービスを提供するため、Cookie を使用することがあります。 Cookie により個人を識別できる情報を収集することはありません。 お客様はブラウザの設定により Cookie の受信を拒否することができます。

9. SSL(Secure Socket Layer)について

当社のウェブサイトはSSLに対応しており、ウェブブラウザとウェブサーバーとの通信を暗号化しています。 お客様が入力する個人情報は自動的に暗号化されて送受信されるため、 万が一、第三者が傍受した場合でも内容を解読することは困難です。

10. プライバシーポリシーの変更

当社は、必要に応じて、本ポリシーの内容を変更することがあります。 変更後のプライバシーポリシーについては、当社ウェブサイトに掲載したときから効力を生じるものとします。

11. お問い合わせ

本ポリシーに関するお問い合わせは、以下の窓口までお願いいたします。

株式会社ゼットリンカー

〒160-0023

東京都新宿区西新宿3丁目3番13号西新宿水間ビル2F

代表取締役: 金原隆利

お問い合わせ先: info@zetlinker.com

制定日:2024年1月1日

最終改訂日:2026/7/20

利用規約

この利用規約(以下、「本規約」といいます。)は、株式会社ゼットリンカー(以下、「当社」といいます。)が 提供するウェブサイトおよびサービス(以下、「本サービス」といいます。)の利用条件を定めるものです。 お客様は、本規約に同意した上で、本サービスをご利用ください。

第1条(適用)

1. 本規約は、お客様と当社との間の本サービスの利用に関わる一切の関係に適用されるものとします。

2. 当社は本サービスに関し、本規約のほか、ご利用にあたってのルール等、各種の定め(以下、「個別規定」といいます。)を することがあります。これら個別規定はその名称のいかんに関わらず、本規約の一部を構成するものとします。

3. 本規約の規定と個別規定の規定が異なる場合は、個別規定において特段の定めなき限り、個別規定の規定が優先されるものとします。

第2条(定義)

本規約において使用する以下の用語は、各々以下に定める意味を有するものとします。

  • 「利用契約」とは、本規約を契約条件として当社とお客様との間で締結される、本サービスの利用契約
  • 「知的財産権」とは、著作権、特許権、実用新案権、意匠権、商標権その他の知的財産権(それらの権利を取得し、またはそれらの権利につき登録等を出願する権利を含みます。)
  • 「投稿データ」とは、お客様が本サービスを利用して投稿その他送信するコンテンツ(文章、画像、動画その他のデータを含みますがこれらに限りません。)

第3条(本サービスの提供)

1. お客様は、本規約に同意の上、当社の定める方法によって利用登録を申請し、当社がこれを承認することによって、本サービスを利用することができるようになります。

2. 当社は、お客様に以下のいずれかの事由があると判断した場合、利用登録の申請を承認しないことがあり、その理由については一切の開示義務を負わないものとします。

  • 利用登録の申請に際して虚偽の事項を届け出た場合
  • 本規約に違反したことがある者からの申請である場合
  • その他、当社が利用登録を相当でないと判断した場合

第4条(ユーザーIDおよびパスワードの管理)

1. お客様は、自己の責任において、本サービスのユーザーIDおよびパスワードを適切に管理するものとします。

2. お客様は、いかなる場合にも、ユーザーIDおよびパスワードを第三者に譲渡または貸与し、もしくは第三者と共用することはできません。

3. 当社は、ユーザーIDとパスワードの組み合わせが登録情報と一致してログインされた場合には、そのユーザーIDを登録しているお客様自身による利用とみなします。

第5条(禁止事項)

お客様は、本サービスの利用にあたり、以下の行為をしてはなりません。

  • 法令または公序良俗に違反する行為
  • 犯罪行為に関連する行為
  • 本サービスの内容等、本サービスに含まれる著作権、商標権ほか知的財産権を侵害する行為
  • 当社、ほかのお客様、またはその他第三者のサーバーまたはネットワークの機能を破壊したり、妨害したりする行為
  • 本サービスによって得られた情報を商業的に利用する行為
  • 当社のサービスの運営を妨害するおそれのある行為
  • 不正アクセスをし、またはこれを試みる行為
  • 他のお客様に関する個人情報等を収集または蓄積する行為
  • 不正な目的を持って本サービスを利用する行為
  • 本サービスの他のお客様またはその他の第三者に不利益、損害、不快感を与える行為
  • 他のお客様に成りすます行為
  • 当社が許諾しない本サービス上での宣伝、広告、勧誘、または営業行為
  • 面識のない異性との出会いを目的とした行為
  • 当社のサービスに関連して、反社会的勢力に対して直接または間接に利益を供与する行為
  • その他、当社が不適切と判断する行為

制定日:2024年1月1日

最終改訂日:2026/7/20