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?
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 :
Possible Solution :
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)