Static vs Dynamic Handlers
Understanding when Route Handlers are cached.
Aggressive Caching
By default, Next.js will statically evaluate GET Route Handlers during the build process.
If you fetch data from a database inside a standard GET handler and return it, that data will be frozen at build time. It will not update when users request the endpoint.
Performance vs Freshness
Static handlers are incredibly fast because they just return a pre-generated JSON string from the CDN.
However, APIs usually need to respond with fresh data (e.g., the latest user profile). In these cases, you must opt out of caching to make the handler Dynamic.
Opting into Dynamic Rendering
POST, PUT, PATCH, and DELETE handlers are *always* dynamic.
To make a GET handler dynamic, you must do one of three things:
1. Use a dynamic function (like cookies() or headers()).
2. Access the URL's query string (request.nextUrl.searchParams).
3. Explicitly export const dynamic = 'force-dynamic' from the file.
The Cache Race
Fire requests at both the Static GET endpoint and the Dynamic GET endpoint. Watch how the Static endpoint always returns the exact same build timestamp, while the Dynamic one updates in real-time.
Cached (Static)
Default Behaviorreturn NextResponse.json({ time });
Uncached (Dynamic)
Opt-in Behaviorreturn NextResponse.json({ time });
Check yourself
Pick an answer to lock it in, then read why. Getting one wrong is part of how it sticks.
Remember this
GETRoute Handlers are statically cached by default.POSTandDELETEhandlers are always dynamic.- Reading
cookies(),headers(), orsearchParamsopts a GET handler into dynamic rendering. - You can explicitly opt out of caching with
export const dynamic = 'force-dynamic'.
Done with this concept?
Mark it complete to track your progress. No login needed.