nitro
nitro copied to clipboard
SWR prevent cache expiration
Environment
Nitro 2.10.4
Reproduction
routeRules: {
'/': { swr: true, maxAge: 60, staleMaxAge: 60 },
},
Describe the bug
The current implementation prevent cache clearing when swr is enabled.
https://github.com/nitrojs/nitro/blame/4a57c822d98701ef8f7a07aff7eb60be4c1888e2/src/runtime/internal/cache.ts#L124
This make the cached value being indefinitely reused and, in some case, massive cache accumulation. For heavy endpoint/functions, disabling swr may not be an option, as it can lead to extended unavailability.
The expected behavior would be to calculate and use the correct ttl using staleMaxAge.
Additional context
No response
Logs
Related to https://github.com/nitrojs/nitro/pull/2783 (@pi0)
Also, what is the expected configuration when "native invalidation" is not supported by the cache driver ? I am misundestranding the issue, does nitro/nuxt ignore the still-existing outdated cache ?
Even if the storage layer has a proper eviction algorithm, not setting a TTL may lead to unnecessary memory usage, suboptimal cache management, and added monitoring complexity.
I'm currently facing an issue with increased cache costs due to this behavior with swr. Here are the changes made:
- Before:
maxAge = x,swrdisabled - After:
maxAge + staleMaxAge = x,swrenabled
The cache storage is Redis with LRU eviction configured.
Cache costs have risen to prevent excessive evictions. Additionally, observability has become more complex since we can no longer rely on the Redis hit ratio since some keys should have expired are still being hit.
I was saw in a production load a memory leak dua a short (5sec) but exists SWR. staleMaxAge was used but not working on production from some reason (using standard memoryCache).
for now, a ugly workaround for the SWR:
const storage = useStorage();
setInterval(async ()=>{
const keys = (await storage.getKeys()).filter(f => f.startsWith("cache:nitro"));
await Promise.all(keys.map(key => storage.removeItem(key)));
}, 20*60000);
place in a server module or server route.