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