Event once revalidateTag is re-cached
Unanswered
Singapura posted this in #help-forum
SingapuraOP
Hi, I'm looking for a way to trigger an event once
The current need for this is because right now there's no way to know when the cache has be rebuilt and ready for clients to view. Once
This results in an event happening, but it can take several seconds for the clients to receive the update. I have also considered doing an optimistic update locally in the client and then it resolves once the new data comes back from the server, but this feels clunky and like it's extra complex on the client.
My original idea was make a separate
Is there a simpler way to do this? I'd prefer not to make the additional
revalidateTag and the corresponding build have completed and the new data is cached. I'm looking for a way to notify several clients via WebSocket that this event has occurred and to re-fetch the data on the client.The current need for this is because right now there's no way to know when the cache has be rebuilt and ready for clients to view. Once
revalidateTag is called, this essentially triggers the cache to invalidate. While the cache is being rebuilt, the client is still receiving cached but stale data while the new cached tag is being populated.This results in an event happening, but it can take several seconds for the clients to receive the update. I have also considered doing an optimistic update locally in the client and then it resolves once the new data comes back from the server, but this feels clunky and like it's extra complex on the client.
My original idea was make a separate
fetch request to my WebSocket server that would broadcast to its clients that an update is available. I had looked at doing this in Middleware after the original fetch request was done, but it looks like NextFetchEvent has been removed in the App Directory.Is there a simpler way to do this? I'd prefer not to make the additional
fetch request within the Route Handler itself.22 Replies
Doing this is honestly unnecessary, because Next.js won’t revalidate the data immediately, on-demand revalidate only purges the data cache. Which means it will cause the next request cannot use the previous cache, it’s not an asynchronous process.
[Learn more about on-demand revalidation](https://nextjs.org/docs/app/building-your-application/caching#on-demand-revalidation)
Therefore, you can just notify the users via websocket after calling revalidate, it must be the latest data.
SingapuraOP
this is unfortunately pretty crucial for my project, as i’m building a realtime log of events that gets distributed to many users at the same time. the project is a log of events that happen in a race that is live streamed, and the user base is the audience watching the race live.
notifying users that a revalidation has occurred (but isn’t necessarily done) is what i was doing and it feels very slow and it feels flaky since refreshing the data doesn’t guarantee that they’ll see the new data.
doesn’t guarantee that they’ll see the new datatbh, this is a totally wrong understanding of how the Next.js cache works
As the docs said, you can always assume users can get the latest data after revalidation
After calling
revalidatePath or revalidateTag, your cache will be purged instantly. It's impossible for the next request to get the stale dataif you really want it to be faster, just send the data via websocket instead of notifying them, but that is no longer related to Next.js
revalidate* is meant for (mostly) static data only; your data doesn’t meet this requirement so doesn’t make a good pair with revalidate*
Just use dynamic data fetching methods; websocket-based real-time data is the way here
SingapuraOP
so on my fetch call, I had specified a number for ‘next.revalidate’ and a value for ‘next.tags’. i wanted something that could be revalidated on demand and time-based. i think this is why i was always receiving stale data on the first request after calling ‘revalidateTag’. since i also specified time-based revalidation, i was getting the ‘stale-while-revalidate’ behavior that is documented.
SingapuraOP
i understand what you’re both saying with “just use websocketsâ€, but that adds additional complexity to the application that i was hoping to avoid. my ideal scenario was that once a new event happens, i could regenerate the cache and then notify all clients once that is done. that way, all clients read from a singular data source vs having to send messages via websockets, continuously poll at an interval with something like swr, and then merge the results together
i want to be fast, but i also want to avoid complexity and lots of reads to my database. i’d like to have this project stay within free tiers if possible
@fuma > doesn’t guarantee that they’ll see the new data
tbh, this is a totally wrong understanding of how the Next.js cache works
As the docs said, you can always assume users can get the latest data after revalidation
Pacific anchoveta
@fuma, are you sure? I'm having problems with revalidateTag myself. Often the data returned is obsolete. And if you look at this link(https://nextjs.org/docs/app/api-reference/functions/revalidateTag), the documentation states that "revalidateTag only invalidates the cache when the path is next visited".
Am I either totally wrong or does the documentation contradict itself regarding "https://nextjs.org/docs/app/building-your-application/caching#on-demand-revalidation" where it says "When an on-demand revalidation is triggered, the appropriate cache entries will be purged from the cache."?
Am I either totally wrong or does the documentation contradict itself regarding "https://nextjs.org/docs/app/building-your-application/caching#on-demand-revalidation" where it says "When an on-demand revalidation is triggered, the appropriate cache entries will be purged from the cache."?
Surly it’s guaranteed that the next request to the page is always latest, since no cache exists.
The only possibility you are not getting the latest data on client-side is that your page has been cached client-side (router cache)
@fuma Surly it’s guaranteed that the next request to the page is always latest, since no cache exists.
Pacific anchoveta
Theoretically yes, but I have encountered problems where the data is not always the most recent. So the documentation leaves me confused at this point.
@fuma The only possibility you are not getting the latest data on client-side is that your page has been cached client-side (router cache)
In this case you may wanna use
router.refresh, i can’t think of another possibility. It might be a bug though (if your code is correct)At least
revalidatePath is working great for my blogPacific anchoveta
Yes, it looks like a bug to me. I researched this issue a lot. I found some people asking about this, and I even found a PR that corrected the page cache in case of revalidation, but I still encounter this type of problem. :/
@fuma At least `revalidatePath` is working great for my blog
Pacific anchoveta
Out of curiosity, which version of Next.js are you using in this project?
13.4.10, not up to date (since I don’t update it frequently)