Unstable_cache doesn't revalidate

We have a wrapper around unstable cache:

import { unstable_cache as next_unstable_cache } from 'next/cache'
import { isTest } from '@/lib/config'

type UnstableCache = typeof next_unstable_cache

/**
 * Allows you to cache the results of expensive operations, like database queries, and reuse them across multiple
 * requests.
 *
 * @param callback This is an asynchronous function that fetches the data you want to cache.
 * It must be a function that returns a Promise.
 * @param keyParts This is an array that identifies the cached key. It must contain globally unique values that together
 * identify the key of the data being cached. The cache key also includes the arguments passed to the function.
 * @param [options] This is an object that controls how the cache behaves. It can contain the following properties:
 * @param [options.tags] An array of tags that can be used to control cache invalidation.
 * @param [options.revalidate] The number of seconds after which the cache should be revalidated. Default is 86400
 * (24 hours in seconds)
 * @returns a function that when invoked, returns a Promise that resolves to the cached data. If the data is not in the
 * cache, the provided function will be invoked, and its result will be cached and returned.
 */
export const unstable_cache: UnstableCache = (callback, keyParts?, options?) => {
  // in test we bypass the cache, return the callback as is
  if (isTest) return callback

  // provide a saner default ttl
  return next_unstable_cache(callback, keyParts, { revalidate: 24 * 60 * 60, ...options })
}

Hopefully we agree that this should by default cache result for 24 hours.

It seems however, as best I have been able to verify, that when I use this wrapper, the data never updates from the originally cached value. In once case it seems to have been cached for at least 21 days.

import { unstable_cache } from '@/lib/api/unstable_cache'
const cachedHubspotOwnerForUserId = unstable_cache(
  (userId, mock) => hubspotOwnerForUserId(userId, mock),
  ['account/executive'],
)

I can control the mock passed in to verify that given differing keys (but same userId) it does return an updated value.

I haven’t found a good way to inspect the data cached using unstable_cache, so I’m hoping you have some insight here.

Best regards,
Christian Sonne

Hey @cers! I have a few questions to get us headed in the right direction.

  • Was revalidate previously set to a different number?
  • Do you get a different result using revalidateTag() or revalidatePath()?
  • What happens if you use 86400 instead of 24 * 60 * 60?
  • Have you sent a Next.js bug report to the team?

Hi Amy! Thanks for your reply.

revalidate was always set to the same number.
I haven’t tried any of those two/three suggestions, can try and report back.
I haven’t filed a bug, but I did find this issue shortly after writing this post: `unstable_cache` with certain value of revalidation interval persisted correctly in production build · Issue #67751 · vercel/next.js · GitHub

In short, someone else has the same issue, exactly with 24 hours too, but not with other values

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.