网页 综合 更新时间 2026-10-15 00:00:00

cacheHandlers

自动蜘蛛 nextjs.org 正文约 5766 字
cacheHandlers
The cacheHandlers configuration allows you to define custom cache storage implementations for 'use cache' and 'use cache: remote'. This enables you to store cached components and functions in external services or customize the caching behavior. 'use cache: private' is not configurable.
Most applications don't need custom cache handlers. The default in-memory cache works well in the typical use case.
Custom cache handlers are for advanced scenarios where you need to either share cache across multiple instances or change where the cache is stored. For example, you can configure a custom remote handler for external storage (like a key-value store), then use 'use cache' in your code for in-memory caching and 'use cache: remote' for the external storage, allowing different caching strategies within the same application.
Sharing cache across instances
The default in-memory cache is isolated to each Next.js process. If you're running multiple servers or containers, each instance will have its own cache that isn't shared with others and is lost on restart.
Custom handlers let you integrate with shared storage systems (like Redis, Memcached, or DynamoDB) that all your Next.js instances can access.
Changing storage type
You might want to store cache differently than the default in-memory approach. You can implement a custom handler to store cache on disk, in a database, or in an external caching service. Reasons include: persistence across restarts, reducing memory usage, or integrating with existing infrastructure.
To configure custom cache handlers:
If you don't configure cacheHandlers, Next.js uses an in-memory LRU (Least Recently Used) cache for both default and remote. You can view the default implementation as a reference.
You can also define additional named handlers (e.g., sessions, analytics) and reference them with 'use cache: <name>'.
Note that 'use cache: private' does not use cache handlers and cannot be customized.
A cache handler stores and returns CacheEntry objects. Both this type and CacheHandler are exported from next/cache:
An entry has the following structure:
Every handler writes entries through set() and serves them through get(). Both methods work with the entry's serialized value, which arrives as a ReadableStream<Uint8Array>. Two properties of that stream constrain every implementation:
How you persist the data is up to you. Buffering the stream and piping it to your store as chunks arrive are both fine, as long as you consume it exactly once. Large entries are worth piping: a page can serialize to a lot of bytes, and an S3-like backend can accept them without your handler holding a second copy.
Two more cases to plan for:
A cache handler must implement the CacheHandler interface with the following five methods.
Store a cache entry for the given cache key.
Returns Promise<void>.
The entry may still be generating when set() is called, so await pendingEntry first. Then consume the value stream and persist what it delivers, as described in The entry value stream.
The example below buffers, which is the simpler option and the right one for an in-memory store. A remote handler can pipe entry.value into an upload instead.
Retrieve a cache entry for the given cache key.
Returns a CacheEntry object if one is stored, or undefined if not.
Your get method should retrieve the cache entry from storage and return undefined when there is nothing stored.
You do not need to check how old the entry is. Next.js compares timestamp against the entry's own expire on every read and treats a too-old entry as a miss. It applies the same check to revalidate when the result is about to be written into another server cache, and it keeps entries a little longer on the dev server so reloads stay fast. Your own age check only duplicates the first of those.
What the two timings mean for you is what Next.js does with the entry you return:
Dropping entries earlier is a policy choice rather than a requirement. The built-in handler drops at revalidate because warming a replacement is wasted work when an in-memory entry is likely to be evicted before anything reads it. A shared store has no such problem and can serve until expire.
Eviction is yours, though. Next.js never deletes from your store, so use a mechanism that reclaims entries nobody reads again: a TTL derived from expire, or a size-bounded LRU like the one in the built-in handler. Checking the age of an entry as you serve it is not eviction, because it only ever reaches the keys that are still being read.
Invalidation is separate from both timings. When a tag tells you an entry is out of date, you have two options:
See Soft Tags and Distributed Tag Coordination for where those invalidations come from.
Wrap your stored data in a new stream on every hit, never the stream you received in set().
Called once per request, before the first cache read for this handler's kind, so the handler can sync tag state from an external service.
Returns Promise<void>.
For in-memory caches, this can be a no-op. For distributed caches, use it to read tag state from an external service or database, so this instance learns about invalidations made by the others before it serves anything from its own store. A request that reads nothing from this handler never calls it.
Get the maximum revalidation timestamp for a set of tags.
If you're not tracking tag revalidation timestamps, return 0. Otherwise, find the most recent revalidation timestamp across all the provided tags. Return Infinity if you prefer to handle soft tag checking in the get method.
Called when tags are revalidated or expired.
Your handler should update its internal state to mark these tags as invalidated.
Whether durations is present tells you which kind of invalidation this is:
访问原文 返回搜索 https://nextjs.org/docs/app/api-reference/config/next-config-js/cacheHandlers
本页为82搜索生成的网页快照,内容来自站内索引;演示数据的原文链接仅作示例。