You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The `'use cache: remote'` directive enables caching in dynamic contexts where regular `use cache` would not work, such as after calling `await connection()`, `await cookies()`, or `await headers()`.
17
+
The `'use cache: remote'` directive enables caching of **shared data**in dynamic contexts where regular [`use cache`](/docs/app/api-reference/directives/use-cache) would not work, for example after calling [`await connection()`](/docs/app/api-reference/functions/connection), [`cookies()`](/docs/app/api-reference/functions/cookies) or [`headers()`](/docs/app/api-reference/functions/headers).
17
18
18
-
> **Good to know:**`'use cache: remote'` is a variant of [`use cache`](/docs/app/api-reference/directives/use-cache) designed specifically for runtime caching in dynamic contexts. Unlike regular `use cache`, it works after dynamic data access and stores results in server-side cache handlers.
19
+
> **Good to know:**
20
+
>
21
+
> - Results are stored in server-side cache handlers and shared across all users.
22
+
> - For **user-specific data** that depends on [`cookies()`](/docs/app/api-reference/functions/cookies) or [`headers()`](/docs/app/api-reference/functions/headers), use [`'use cache: private'`](/docs/app/api-reference/directives/use-cache-private) instead to avoid accidentally sharing personalized data between users.
19
23
20
24
## Usage
21
25
@@ -67,13 +71,13 @@ export default async function ProductPage({
// Ensure this component is never cached in the static shell
111
-
// by requiring a connection. This makes it dynamic.
117
+
// Calling connection() makes this component dynamic, preventing
118
+
// it from being included in the static shell. This ensures the price
119
+
// is always fetched at request time.
112
120
awaitconnection()
113
121
114
-
// Since we're in a dynamic context (after connection()),
115
-
// using "use cache" would NOT cache at all. We need "use cache: remote"
116
-
// to cache at runtime in a remote cache handler.
122
+
// Now we can cache the price in a remote cache handler.
123
+
// Regular 'use cache' would NOT work here because we're in a dynamic context.
117
124
constprice=awaitgetProductPrice(productId)
118
125
119
126
return<div>Price: ${price}</div>
@@ -122,13 +129,16 @@ async function ProductPrice({ productId }) {
122
129
asyncfunctiongetProductPrice(productId) {
123
130
'use cache: remote'
124
131
cacheTag(`product-price-${productId}`)
125
-
cacheLife({ stale:3600 }) // 1 hour
126
132
133
+
// Client uses cached value for 1 hour
134
+
cacheLife({ stale:3600 })
135
+
136
+
// This database query is cached and shared across all users
127
137
returndb.products.getPrice(productId)
128
138
}
129
139
```
130
140
131
-
> **Note:** Regular `use cache` will not cache anything when used in a dynamic context (after `await connection()`, `await cookies()`, `await headers()`, etc.). Use `'use cache: remote'` to enable runtime caching in these scenarios.
141
+
> **Note:** Regular [`use cache`](/docs/app/api-reference/directives/use-cache) will not cache anything when used in a [dynamic context](/docs/app/getting-started/partial-prerendering#dynamic-rendering) (after [`await connection()`](/docs/app/api-reference/functions/connection), [`await cookies()`](/docs/app/api-reference/functions/cookies), [`await headers()`](/docs/app/api-reference/functions/headers), etc.). Use `'use cache: remote'` to enable runtime caching in these scenarios.
132
142
133
143
## Difference from `use cache` and `use cache: private`
134
144
@@ -147,15 +157,33 @@ Next.js provides three caching directives, each designed for different use cases
147
157
148
158
### When to use each
149
159
150
-
-**`use cache`**: Use for static content that can be prerendered at build time and doesn't depend on request-specific data.
151
-
-**`'use cache: remote'`**: Use when caching is needed after dynamic data access (`connection()`) or for per-request caching of shared data.
152
-
-**`'use cache: private'`**: Use for user-specific content that needs to be runtime prefetched and depends on cookies, headers, or search params.
160
+
Choose the right caching directive based on your use case:
- Content is personalized per-user (depends on cookies, headers)
177
+
- You need [runtime prefetching](/docs/app/guides/prefetching) of user-specific content
178
+
- Content should never be shared between users
153
179
154
180
## How it works
155
181
182
+
The `'use cache: remote'` directive enables runtime caching of shared data in dynamic contexts by storing results in server-side cache handlers rather than prerendering at build time.
183
+
156
184
### Dynamic context detection
157
185
158
-
When Next.js encounters certain APIs like `connection()`, `cookies()`, or `headers()`, the context becomes "dynamic". In a dynamic context:
186
+
When Next.js encounters certain APIs like [`connection()`](/docs/app/api-reference/functions/connection), [`cookies()`](/docs/app/api-reference/functions/cookies), or [`headers()`](/docs/app/api-reference/functions/headers), the context becomes "[dynamic](/docs/app/getting-started/partial-prerendering#dynamic-rendering)". In a dynamic context:
159
187
160
188
1.**Regular `use cache` stops working** - it won't cache anything
161
189
2.**`'use cache: remote'` continues to work** - it caches in the remote cache handler
@@ -176,21 +204,21 @@ This means:
176
204
177
205
1. Cached data is shared across all users and requests
178
206
2. Cache entries persist beyond a single session
179
-
3. Cache invalidation works via `cacheTag` and `revalidateTag`
180
-
4. Cache expiration is controlled by `cacheLife` configuration
207
+
3. Cache invalidation works via [`cacheTag`](/docs/app/api-reference/functions/cacheTag) and [`revalidateTag`](/docs/app/api-reference/functions/revalidateTag)
208
+
4. Cache expiration is controlled by [`cacheLife`](/docs/app/api-reference/functions/cacheLife) configuration
181
209
182
210
### Dynamic context example
183
211
184
212
```tsx
185
213
asyncfunction UserDashboard() {
186
-
//This call makes the context dynamic
214
+
//Calling connection() makes the context dynamic
187
215
awaitconnection()
188
216
189
-
//Regular 'use cache' would NOT cache here
190
-
const stats =awaitgetStats()// Not cached with 'use cache'
217
+
//Without any caching directive, this runs on every request
218
+
const stats =awaitgetStats()
191
219
192
-
//But 'use cache: remote' WILL cache here
193
-
const analytics =awaitgetAnalytics()// Cached with 'use cache: remote'
220
+
//With 'use cache: remote', this is cached in the remote handler
221
+
const analytics =awaitgetAnalytics()
194
222
195
223
return (
196
224
<div>
@@ -202,21 +230,25 @@ async function UserDashboard() {
202
230
203
231
asyncfunction getAnalytics() {
204
232
'use cache: remote'
205
-
cacheLife({ stale: 300 }) // 5 minutes
233
+
234
+
// Client uses cached value for 5 minutes
235
+
cacheLife({ stale: 300 })
236
+
237
+
// This expensive operation is cached and shared across all requests
206
238
returnfetchAnalyticsData()
207
239
}
208
240
```
209
241
210
242
## Request APIs and remote caches
211
243
212
-
While `'use cache: remote'` technically allows access to request-specific APIs like `cookies()` and `headers()`, it's generally not recommended to use them together:
244
+
While `'use cache: remote'` technically allows access to request-specific APIs like [`cookies()`](/docs/app/api-reference/functions/cookies) and [`headers()`](/docs/app/api-reference/functions/headers), it's generally not recommended to use them together:
213
245
214
-
| API | Allowed in `use cache`| Allowed in `'use cache: remote'`| Recommended |
|[`cookies()`](/docs/app/api-reference/functions/cookies)| No | Yes (not recommended) | Use [`'use cache: private'`](/docs/app/api-reference/directives/use-cache-private) instead |
249
+
|[`headers()`](/docs/app/api-reference/functions/headers)| No | Yes (not recommended) | Use [`'use cache: private'`](/docs/app/api-reference/directives/use-cache-private) instead |
250
+
|[`connection()`](/docs/app/api-reference/functions/connection)| No | Yes | Yes - this is the primary use case|
251
+
|[`searchParams`](/docs/app/api-reference/file-conventions/page#searchparams-optional)| No | Yes (not recommended) | Use [`'use cache: private'`](/docs/app/api-reference/directives/use-cache-private) instead |
220
252
221
253
> **Important:** If you need to cache based on cookies, headers, or search params, use [`'use cache: private'`](/docs/app/api-reference/directives/use-cache-private) instead. Remote caches are shared across all users, so caching user-specific data in them can lead to incorrect results being served to different users.
222
254
@@ -302,9 +334,12 @@ export default async function DashboardPage() {
302
334
asyncfunction getGlobalStats() {
303
335
'use cache: remote'
304
336
cacheTag('global-stats')
305
-
cacheLife({ stale: 60 }) // 1 minute
306
337
307
-
// Expensive database query - cached for all users
338
+
// Client uses cached value for 1 minute
339
+
cacheLife({ stale: 60 })
340
+
341
+
// This expensive database query is cached and shared across all users,
342
+
// reducing load on your database
308
343
const stats =awaitdb.analytics.aggregate({
309
344
total_users: 'count',
310
345
active_sessions: 'count',
@@ -346,9 +381,11 @@ async function FeedItems() {
346
381
asyncfunction getFeedItems() {
347
382
'use cache: remote'
348
383
cacheTag('feed-items')
349
-
cacheLife({ stale: 120 }) // 2 minutes
350
384
351
-
// Fetch from external API
385
+
// Client uses cached value for 2 minutes
386
+
cacheLife({ stale: 120 })
387
+
388
+
// This API call is cached, reducing requests to your external service
@@ -459,10 +509,10 @@ async function ProductRecommendations({ productId }) {
459
509
> **Good to know**:
460
510
>
461
511
> - Remote caches are stored in server-side cache handlers and shared across all users
462
-
> - Remote caches work in dynamic contexts where regular `use cache` would fail
463
-
> - Use `cacheTag()` and `revalidateTag()` to invalidate remote caches on-demand
464
-
> - Use `cacheLife()` to configure cache expiration
465
-
> - For user-specific data, use `'use cache: private'` instead of `'use cache: remote'`
512
+
> - Remote caches work in [dynamic contexts](/docs/app/getting-started/partial-prerendering#dynamic-rendering) where regular [`use cache`](/docs/app/api-reference/directives/use-cache) would fail
513
+
> - Use [`cacheTag()`](/docs/app/api-reference/functions/cacheTag) and [`revalidateTag()`](/docs/app/api-reference/functions/revalidateTag) to invalidate remote caches on-demand
514
+
> - Use [`cacheLife()`](/docs/app/api-reference/functions/cacheLife) to configure cache expiration
515
+
> - For user-specific data, use [`'use cache: private'`](/docs/app/api-reference/directives/use-cache-private) instead of `'use cache: remote'`
466
516
> - Remote caches reduce origin load by storing computed or fetched data server-side
0 commit comments