next.jscachingcookiescomponentsprisma

Next.js 16 Cache Components: Why is my cache() function still hitting the database on every request despite using next: { revalidate: 3600 }?


I'm using Next.js 16 with Cache Components (cache() from React) to deduplicate and cache database queries across layouts and pages.

Here's my setup:

// lib/data.ts

import { cache } from 'react';
import db from '@/lib/db';
export const getUser = cache(async (userId: string) => {
  console.log('Fetching user from DB...', userId);
  return await db.user.findUnique({
    where: { id: userId },
    next: { revalidate: 3600, tags: ['user'] } // 1 hour cache
  });
});

// app/layout.tsx

import { getUser } from '@/lib/data';

export default async function RootLayout({ children }) {
  const user = await getUser('123'); // Should be cached
  return (
    <html>
      <body>
        <Header user={user} />
        {children}
      </body>
    </html>
  );
}

// app/dashboard/page.tsx

import { getUser } from '@/lib/data';

export default async function DashboardPage() {
  const user = await getUser('123'); // Same ID — should reuse cache
  return <Dashboard user={user} />;
}

Expected behavior:

Actual behavior:

What I've tried:

Question:

Why is the Data Cache not respecting revalidate when using cache()? Is there a known limitation when combining cache() + next: { revalidate } in Prisma queries?

How can I debug if the cache key is being generated correctly?

Next.js: 16.0.0 React: 19.0.0 Prisma: 5.15.0

Any help or workaround would be appreciated!


Solution

  • Your code would work with fetch requests, but since you're using Prisma, you have 2 ways to solve this.

    #1 Use unstable_cache to cache the DB query:

    import { unstable_cache } from 'next/cache'
    import db from '@/lib/db'
    
    export const getUser = unstable_cache(
      async (userId: string) => {
        console.log('Fetching user from DB...', userId)
        return db.user.findUnique({ where: { id: userId } })
      },
      ['getUser'],
      { revalidate: 3_600, tags: ['user'] }
    )
    

    #2 Using Prisma-native way of caching and revalidation:

    NOTE: Don't quote me on this, but looks like it will only work if you have Prisma Accelerate enabled.

    return await db.user.findUnique({
        where: { id: userId },
        cacheStrategy: { ttl: 3_600 },
    });