AI & Agent Dev Bug Sandbox logo
AI & Agent Dev Bug Sandbox
Back to Radar

Partial Prefetching Causes Redundant User Database Lookups In Documented Auth Cache Pattern

Following the Authentication with Cache Components guide with 'use cache: private' leads to one DB query per prefetched page link, multiplying user lookups. The documented pattern does not share cached user data across independent PPR requests.

mediumConfidence 85%Next.js

Origin Analysis

The guide recommends marking getCurrentUser with 'use cache: private', which caches the function result scoped to the current request context. Partial Prefetching renders linked pages in separate server requests, each with its own context, so the cache key differs and no cache reuse occurs, triggering a fresh DB query for every prefetched page.
1. Follow the official guide to create a getCurrentUser function with 'use cache: private'. 2. Enable Partial Prefetching (PPR) in next.config. 3. Visit a page that contains links to other pages that also call getCurrentUser. 4. Inspect network requests or backend logs; observe multiple user DB lookups corresponding to each prefetched link.

Fixing Code Block

import { unstable_cache as cache } from 'next/cache' import { getSession } from '@/lib/session' import { db } from '@/lib/db' export async function getCurrentUser() { const session = await getSession() if (!session?.user) return null const userId = session.user.id return cache( async () => { // Perform DB lookup inside cached function return await db.user.findUnique({ where: { id: userId } }) }, [`user-${userId}`], { tags: [`user-${userId}`], revalidate: 3600, // 1 hour, adjust as needed } )() }
This replaces the per-request 'use cache: private' with unstable_cache using a stable cache key derived from the user ID. Since the key is the same across all requests from the same user (regardless of PPR context), the cached user object is reused, eliminating redundant DB lookups. The tags allow targeted invalidation when user data changes.

Edge Case Audit

Introduces a TTL-based cache that may serve stale user data until revalidation. Ensure you invalidate the tag (e.g., revalidateTag(`user-${userId}`)) whenever user data changes. If your session retrieval itself performs a DB query, that query will still run per request; ensure getSession is lightweight (e.g., JWT decode). For multi-instance deployments, use a shared cache backend. Rollback: revert to the original 'use cache: private' implementation; the current performance issue will return but data freshness guarantees are restored.

Ecosystem Topology