ISR revalidation is using stale fetch data
Unanswered
Silky ant posted this in #help-forum
Silky antOP
The following code (usually) only updates the fetch date on every second page revalidate. Causing the same data to stick for 10+ seconds instead of 5+ seconds.
Here is the repro @B33fb0n3 https://github.com/hallatore/revalidate-bug
Issue link: https://github.com/vercel/next.js/issues/58909
Example code:
Here is the repro @B33fb0n3 https://github.com/hallatore/revalidate-bug
Issue link: https://github.com/vercel/next.js/issues/58909
Example code:
async function Page() {
const response = await fetch(
"http://worldtimeapi.org/api/timezone/Europe/Oslo",
{
next: {
revalidate: 5,
},
}
);
const json = (await response.json()) as { datetime: string };
return (
<div>
<h1>Time should update every 5 seconds. Not every 10.</h1>
<p>local: {new Date().toLocaleTimeString()}</p>
<p>fetch: {json.datetime.substring(11, 19)}</p>
</div>
);
}
export default Page;12 Replies
Silky antOP
I would expect
Note: You need to build and start the app, since the page needs to be static.
json.datetime.substring(11, 19) to update every 5+ seconds (not exactly 5, but soon after page regeneration has happened)Note: You need to build and start the app, since the page needs to be static.
perfect, thanks!
I will take a look at it, but don't rely on me. I find that very interesting. If solutions are found in the meantime, I'll see it here in this thread 🙂
Silky antOP
Found it. It's a race condition bug.
If I stick a 100ms delay at the start of the function, fetch always returns correct data.
If I stick a 100ms delay at the start of the function, fetch always returns correct data.
await new Promise((resolve) => setTimeout(resolve, 100));lol xD
Well, good job I guess ^^
Silky antOP
Before and after. switches to 100ms delay halfway in the video.
nice, that looks good ðŸ‘
Silky antOP
Figured it out in the end 🙂
https://github.com/vercel/next.js/pull/58926
https://github.com/vercel/next.js/pull/58926
Black Caiman
Hey @Silky ant thanks for finding this and submitting a PR. I’m having a frustrating issue where I am calling revalidatePath and router.refresh on a action to add a new post to my site, and yet only half the time do I see new data. At first I was thinking the issue was a race condition between revalidatePath taking effect and router.refresh but looks like it might be what you found!
Is there anyway to test your change to see?
Is there anyway to test your change to see?
Silky antOP
If you download the pr branch and build it you can use a file link in packages to the packages/next folder in the next project.
Aslo I had some issue with the current build locally, so I had to add a placeholder
"next": "file:f:/projects/next/packages/next" @Black Caiman Aslo I had some issue with the current build locally, so I had to add a placeholder
pages/_error.tsx. So if you get an error about error page you can just add that file with this."use client";
export const dynamic = "force-dynamic";
function Error() {
return <div>404</div>;
}
export default Error;Black Caiman
Thanks! I think I actually found the issue I was having. It is only re-creatable while deployed to Vercel.
Basically, I have a route handler that is calling revalidatePath and 99% of the time it works. However, I have found that Vercel's cache will still return a "X-Vercel-Cache: HIT" if you happen to call revalidatePath right around when the cache is being revalidated (in my case the age of the cache was just 8 seconds).
Even though revalidatePath was called when the age was ~6 seconds, it didn't seem to regenerate the Vercel page cache, and I still get HIT instead of the expected REVALIDATE that happens the other 99% of the time.
When running locally with npm run build then start, the X-Nextjs-Cache headers are as expected - they are always MISS right after a revalidatePath.
Submitted a Github issue for it: https://github.com/vercel/next.js/issues/59044
Basically, I have a route handler that is calling revalidatePath and 99% of the time it works. However, I have found that Vercel's cache will still return a "X-Vercel-Cache: HIT" if you happen to call revalidatePath right around when the cache is being revalidated (in my case the age of the cache was just 8 seconds).
Even though revalidatePath was called when the age was ~6 seconds, it didn't seem to regenerate the Vercel page cache, and I still get HIT instead of the expected REVALIDATE that happens the other 99% of the time.
When running locally with npm run build then start, the X-Nextjs-Cache headers are as expected - they are always MISS right after a revalidatePath.
Submitted a Github issue for it: https://github.com/vercel/next.js/issues/59044