Search code examples
next.jscachingvercel

NextJS 14 - Cache not revalidating on Vercel servers


I've got a project where on my homepage I've got some stats about it. As I don't want to fetch this from database every time, I tried to implement some caching here. However it seems cache not get invalidated correctly on vercel servers.

My code: I've got client component which fetch data from API:

  const [data, setData] = useState<HomePageAllStats>(null as any);

  useEffect(() => {
    const fetchData = async () => {
      const response = await fetch(`URL/api/stats`, { cache: 'no-store' });
      const data = await response.json();
      setData(data);
    };

    fetchData();
  }, []);
}

In client component I obviously don't have any caching. After that I have my api route:

export async function GET() {
  try {
    const statsPromise = unstable_cache(getStats, ['stats'], { revalidate: 60 });
    const stats = await statsPromise();
    const mappedCountryStats = mapStats(stats.source);
    const data: HomePageAllStats = {
      totalCount: stats.total,
      countries: mappedCountryStats,
    };
    return Response.json(data);
  } catch (error) {
    console.error('Error getting stats:', error);
    return Response.json({});
  }
}

async function getStats(): Promise<TotalStats> {
  const documentReference = await admin.firestore().collection('stats').doc('total').get();
  return documentReference.data() as TotalStats;
}

Here I'm using unstable_cache for 60 seconds revalidation. (I prefer to revalidate on server not client, so someone can not spam my API and always get new resutls).

Issue: It seems like if I build this code with build and start command, everything works fine, after 1 minute cache get revalidated and shows new results.

When I deploy it on vercel it behave strange. First request after build show new results from database. But after I do full page reload some old data load from a cache. Which was valid like day ago or something.

Any idea what can be wrong with my code? Or what I can try to fix it?


Solution

  • Problem :

    I'm using unstable_cache for 60 seconds revalidation. It seems like if I build this code with build and start command, everything works fine, after 1 minute cache get revalidated and shows new results.When I deploy it on vercel it behave strange. First request after build show new results from database. But after I do full page reload some old data load from a cache. Which was valid like day ago or something.

    Possible Cause :

    • You used unstable_cache : There is a warning1 that this is API, is unstable and may change in the future.

    Possible Solution :

    • Route Segment Config allows you to configure the behavior of a page, layout, or route handler by setting various options 3.

    Add export const revalidate = 60 at top of route file /api/stats this will set revalidation frequency to 60 seconds.

    export const revalidate = 60
    export async function GET() {
    ...
    ...
    
    }
    

    So API calls coming under 60 seconds will get same data, after 60 seconds data will be re-fetched on API call cached & then given.

    Please Read :

    If you have any doubts, then please leave a comment (I will update answer if necessary)