typescriptadvanced
Caching Strategies in Next.js
Master Next.js caching with fetch cache, unstable_cache, revalidatePath, and revalidateTag patterns.
typescriptPress ⌘/Ctrl + Shift + C to copy
import { unstable_cache } from 'next/cache';
import { revalidatePath, revalidateTag } from 'next/cache';
// 1. Fetch with time-based revalidation
async function getProducts() {
const res = await fetch('https://api.example.com/products', {
next: { revalidate: 3600 }, // Revalidate every hour
});
return res.json();
}
// 2. Fetch with tag-based revalidation
async function getProduct(id: string) {
const res = await fetch(`https://api.example.com/products/${id}`, {
next: { tags: [`product-${id}`, 'products'] },
});
return res.json();
}
// 3. Cache non-fetch data (database queries, computations)
const getCachedUser = unstable_cache(
async (userId: string) => {
// Simulated DB query
console.log(`DB query for user: ${userId}`);
return { id: userId, name: 'Alice', role: 'admin' };
},
['user'], // Cache key prefix
{
revalidate: 900, // 15 minutes
tags: ['users'], // Tag for manual invalidation
},
);
// 4. Cache with dynamic keys
const getCachedAnalytics = unstable_cache(
async (period: string) => {
return { period, views: 12345, visitors: 6789 };
},
['analytics'],
{ revalidate: 300, tags: ['analytics'] },
);
// 5. Server Action for revalidation
async function updateProduct(formData: FormData) {
'use server';
const id = formData.get('id') as string;
// ... update in DB
// Revalidate specific product cache
revalidateTag(`product-${id}`);
// Or revalidate by path
revalidatePath(`/products/${id}`);
// Or revalidate all products
// revalidateTag('products');
}
// 6. No-cache for dynamic data
async function getCurrentUser() {
const res = await fetch('https://api.example.com/me', {
cache: 'no-store', // Always fresh
});
return res.json();
}
// Page component using cached data
export default async function ProductPage({ params }: { params: { id: string } }) {
const [product, user, analytics] = await Promise.all([
getProduct(params.id),
getCachedUser('user-1'),
getCachedAnalytics('7d'),
]);
return (
<div>
<h1>{product.name}</h1>
<p>Welcome, {user.name}</p>
<p>Views: {analytics.views}</p>
</div>
);
}Sponsored
Vercel
Use Cases
- ISR page caching
- Database query caching
- On-demand cache invalidation
Tags
Related Snippets
Similar patterns you can reuse in the same workflow.
typescriptintermediate
Next.js ISR & On-Demand Revalidation
Configure Incremental Static Regeneration with time-based and on-demand revalidation strategies.
Best for: Caching CMS content with periodic refresh
#nextjs#isr
typescriptadvanced
On-Demand ISR Revalidation
Trigger incremental static regeneration via API route with secret token validation for instant cache purge.
Best for: CMS content updates
#isr#revalidation
typescriptintermediate
Next.js Streaming with Suspense
Stream server components with Suspense boundaries for progressive page loading and better TTFB.
Best for: Progressive loading for data-heavy dashboards
#nextjs#streaming
typescriptbeginner
Next.js Image Optimization Patterns
Advanced next/image usage with responsive sizes, blur placeholders, and custom loaders.
Best for: Optimizing Core Web Vitals with proper image loading
#nextjs#image