Quick wins for a faster PC:
Repair Windows errors before they cause bigger problemsFix Now →Fix the driver behind crashes, sound loss and screen glitchesFind Drivers →Clear out junk files and repair common Windows errorsFree Scan →iTechGuides is reader-supported. When you buy through links on our site, we may earn an affiliate commission. As an Amazon Associate I earn from qualifying purchases. Learn more
In Next.js applications using the Cache Components model, enable cacheComponents, put 'use cache' around work that is safe to reuse, and choose a freshness profile with cacheLife. Add tags for shared data that mutations must invalidate; use updateTag when a Server Action needs an immediate update, revalidateTag when stale-while-revalidate is acceptable, and revalidatePath when the route is the target. Read request-specific values outside the cached scope and pass only the values the cached work needs.
These instructions describe Cache Components, not every Next.js application. The Next.js documentation maintains a separate guide for the previous caching model. Check your installed Next.js version and configuration before adopting either set of APIs; the documentation cited here was updated in February and March 2026.
How do I enable and use the Cache Components model?
Cache Components must be enabled before using the 'use cache', cacheLife, and related patterns described here. In a TypeScript configuration file, the setting looks like this:
import type { NextConfig } from 'next'
const nextConfig: NextConfig = {
cacheComponents: true,
}
export default nextConfig
Place 'use cache' at the top of a route, component, or function whose result can be reused. A data function is often the clearest boundary: it makes the cached work explicit and gives you one place to set freshness and invalidation behavior.
#1 Best Overall
import { cacheLife, cacheTag } from 'next/cache'
async function getProducts() {
'use cache'
cacheLife('hours')
cacheTag('products')
return db.product.findMany()
}
The built-in default cache profile documents five minutes of client stale time and fifteen minutes until server revalidation, with no time-based expiration. Choose a profile deliberately rather than assuming that every cached value has one simple time-to-live.
How should I think about cache freshness?
cacheLife separates three timing questions. In a custom profile, its values are expressed in seconds:
stale: how long the client router may use cached data without contacting the server.revalidate: how often the server refreshes the cached result.expire: the maximum time stale content can remain before a request must wait for fresh content.
For example, this profile uses illustrative values of 60, 300, and 3600 seconds; they are not universal recommendations:
Free tools Windows power users keep installed
One-click scans. No signup required.
Rank #2
cacheLife({
stale: 60,
revalidate: 300,
expire: 3600,
})
Set these values according to the data’s acceptable staleness and the experience the product requires. A short client stale interval does not itself mean the server refreshes every minute, and a revalidation interval is not the same as a hard expiration.
How do I invalidate cached data after a mutation?
Choose the invalidation API based on both scope and user experience. Tags identify cached data by relationship; paths target a route. The current API reference documents these alternatives:
| API | Target | Update behavior |
|---|---|---|
updateTag(tag) |
Cached entries carrying the tag | Use in a Server Action when the user should see the updated data immediately. |
revalidateTag(tag, 'max') |
Cached entries carrying the tag | Marks the tagged data stale; the documented 'max' profile uses stale-while-revalidate behavior. |
revalidatePath(path) |
A route path | Revalidates data associated with the specified path. |
For instance, a Server Action that updates a product can invalidate the shared product data after the write succeeds:
Rank #3
'use server'
import { updateTag } from 'next/cache'
export async function renameProduct(id: string, name: string) {
await db.product.update({ where: { id }, data: { name } })
updateTag('products')
}
Use revalidateTag('products', 'max') instead if briefly serving stale content while fresh data is obtained is acceptable. Use revalidatePath('/products') when the route itself is the intended invalidation target. A tag is useful when multiple cached functions or views depend on the same data; a path is useful when the route is the unit you want to refresh. The one-argument form revalidateTag(tag) is deprecated; follow the current API signature rather than copying older examples.
The Tool Desk
Outbyte Driver Updater FREEScan for outdated or missing drivers - takes under a minuteDriver Scan →Outbyte PC Repair FREEClear out junk files and repair common Windows errorsFree Scan →How do I cache data that depends on cookies or headers?
Request-specific APIs such as cookies and headers belong outside a cached scope. Read the needed value first, then pass it as an argument to the cached function:
import { cookies } from 'next/headers'
async function getAccountView(userId: string) {
'use cache'
return db.account.findFirst({ where: { userId } })
}
export default async function AccountPage() {
const cookieStore = await cookies()
const userId = cookieStore.get('user-id')?.value
if (!userId) return <p>Sign in to view your account.</p>
const account = await getAccountView(userId)
return <AccountDetails account={account} />
}
Arguments contribute to distinct cached results, so a user identifier can separate results for different users. That does not automatically make arbitrary personalized output safe to cache: pass the correct identity or other relevant scope, and ensure the returned content is safe to reuse for requests with the same cache inputs. Do not read a request value inside the cached function and assume the cache will distinguish users for you.
How do I use caching in a Route Handler?
Do not put 'use cache' directly in a Route Handler body. Put the cache directive in a helper that the handler calls, then return its result using the normal response API:
import { cacheLife, cacheTag } from 'next/cache'
async function getCatalog() {
'use cache'
cacheLife('hours')
cacheTag('catalog')
return db.product.findMany()
}
export async function GET() {
const catalog = await getCatalog()
return Response.json(catalog)
}
When a new request arrives, the cached helper’s data follows its configured cacheLife behavior. Keep request-dependent logic in the handler or pass the required values into a helper that can safely distinguish its cached results.
When is a remote cache handler worth considering?
The 'use cache: remote' directive uses a platform-provided cache handler. It may suit deployments where in-memory runtime caching is insufficient, but it introduces network round trips and may involve platform charges. Evaluate it against the application’s workload and deployment topology, including whether instances need shared cached data. The documentation does not establish which provider is fastest, least expensive, or most reliable, so those choices require platform-specific evaluation rather than an assumed performance win.
How does this differ from the previous Next.js caching model?
Next.js documents a separate caching guide for applications that do not use Cache Components. Do not mix its examples or assumptions with the model above.
- In the previous model, the extended server
fetchAPI has persistent Data Cache semantics.cache: 'force-cache'consults the Data Cache, andnext.revalidatesets a maximum cache lifetime. - Conflicting fetch options such as
cache: 'no-store'together with a positivenext.revalidatevalue are not allowed. - The previous-model guide covers explicit fetch caching and
unstable_cachefor non-fetch functions. Those examples are not substitutes for Cache Components APIs in an application using that model.
Cache Components require the Node.js runtime; the documentation says not to use them with the Edge Runtime. Confirm the supported configuration against the Next.js version installed in your project.
How should I choose a pattern?
- Use a cached function or component when its output is safe to reuse and its inputs define the right cache boundary.
- Use
cacheLifeto express client stale time, server refresh frequency, and the point when a request must wait for fresh content. - Use tags for shared data relationships and paths for route-level invalidation.
- Use immediate invalidation after a mutation when the flow requires fresh data at once; use stale-while-revalidate when a short delay is acceptable.
- Consider a remote handler only after accounting for shared-cache needs, network cost, and platform fees.
Cache profiles and APIs describe behavior, not a guaranteed speedup. Measure the application under its actual request mix and deployment conditions before making performance claims.
Windows Errors? Fix Them Before They Spread
Repair common Windows errors and clear accumulated junk for a smoother, more stable PC - no reinstall needed.Free scan · no reinstallOutdated Drivers Are Slowing You Down
One free scan finds every outdated or missing driver and matches the right update for your exact hardware.Free scan · exact hardware matchQuick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

