What Next.js doesn't tell you about caching...

Поділитися
Вставка
  • Опубліковано 7 січ 2025

КОМЕНТАРІ • 73

  • @mariusespejo
    @mariusespejo  Рік тому +13

    Just wanted to clarify: when I was trying to demo the 30s ttl, I should not have hit refresh just before (which might’ve already cleared the cache). I meant to show that clicking quickly shows cached data, but after 30 seconds it gets you a new one. Sorry I totally messed up 😂 but I hope it makes sense!

    • @AldisSv
      @AldisSv Рік тому +1

      Thanks Marius for clearing this up. Btw, I learn't these 30 seconds the hard way, just clicking back and forth with tag, and seeing that suddenly it starts behaving dynamically after some time. It started to fetch data on server side on each navigation. I just dont understand why it's not working like that right from the beginning, why exactly we need to wait those 30 seconds...

  • @WebDevCody
    @WebDevCody Рік тому +20

    yup, I ran into this a while back and it's very annoying. The only fix I found it to add a client component on the page you know should be fresh data each time, and put a router.refresh() inside a useEffect on mount.

    • @EnesKab
      @EnesKab 9 місяців тому +1

      Dude ! I am pulling my hair for the last 5 hours and your comment did the trick finally ! Thank you !

  • @divinelogik
    @divinelogik 11 місяців тому +3

    Jesus dude. This is exactly what I was looking for. I legit tried all 5 strategies for blowing away the cache (no-store, force-dynamic, force-no-store, revalidate=0, React unstable cache), and to find that I was affecting only the server-side cache was mind-boggling. But this makes total sense. Short story: use to kill it entirely.

  • @MMEDHAT1910
    @MMEDHAT1910 Рік тому

    Hello Marius, your videos are great and of huge benefit. I started learning nest js by watching your videos. Keep going ❤️❤️

  • @noeldolan518
    @noeldolan518 Рік тому +1

    Great video! :). BTW what is the flow diagram UI tools you're using @ 4:00?

  • @liu-river
    @liu-river Рік тому +4

    Appreciate the explanation. Any chance you could do a video on deep dive on Next js caching and revalidation including, data cache, route cache, etc?

    • @mariusespejo
      @mariusespejo  Рік тому +2

      Yeah I’ve actually been learning a lot about it in my own projects, I can definitely cover that in more detail. Have you seen the new docs for it? It didn’t exist at the time of this video

    • @liu-river
      @liu-river Рік тому

      @@mariusespejo I have, it's not very beginner friendly. I kinda understand it but it gets quite complicated. Maybe it's one of those things that you will have to play with a lot and try out all different scenarios to fully grasp.

    • @mariusespejo
      @mariusespejo  Рік тому

      Yeah I agree, I’ve had to read it multiple times to be honest and parts of it is still confusing haha

    • @liu-river
      @liu-river Рік тому

      @@mariusespejo yeah, quick question though do you know if server cache actually works in dev mode, or is it production only?

    • @mariusespejo
      @mariusespejo  Рік тому

      “Data cache” (server) I’m pretty does work in development because when I call fetch server-side the terminal logs tell me if they are cache HIT or MISS. If you look in the .next folder you also will see cached data in there. Although I have seen people saying cache doesn’t work in dev mode and what’s tricky is there are multiple caches right, and idk what people are talking about exactly. The docs does say however that link prefetching only works in production, and prefetching affects the “Route Cache” (client) behavior.

  • @ayushjain7023
    @ayushjain7023 Рік тому +5

    To fix it just create a client component returning null, with router.refresh() inside a useeffect with empty dependency array, and add it in a server component, boom 💥 it will work

    • @mariusespejo
      @mariusespejo  Рік тому +6

      Right, however It’s more of a hack than a fix. Nextjs needs to create a way to opt-out

  • @_bouwer
    @_bouwer Рік тому

    Oh my gosh, thanks for this. Hopefully the docs get updated soon.

    • @mariusespejo
      @mariusespejo  Рік тому +1

      just an hour ago actually they posted a response/discussion on the github issue, where they fully explain why this 30s thing exists. It’s probably the best explanation we’ll get. I might cover it in a follow up video if I get some time

  • @dawid_dahl
    @dawid_dahl Рік тому

    Thanks so much for making a video trying to clarify this. Very important stuff. 🙏🏻

  • @oscarresonable2008
    @oscarresonable2008 Рік тому

    Very insightful. I'm actually scratching my head all day long wth is going on 😂😂. As always, Thanks Marius. Keep going brother.

  • @iPankBMW
    @iPankBMW Рік тому

    Thank you for this video! I went immediately to Nextjs docs and red the latest instructions - now they are mentioning it. And they say there is no way to opt out of the default 30 seconds server component payload cache (cliend-side/router-cache). That terible. So there is no way we can use server components for data fetching if you always need latest data from backend… So useless.. Gues for latest data from backend we still need to stack to client side components…

  • @SamTipton
    @SamTipton Рік тому

    I've only been learning next for just a week now, but this caching behavior makes sense to me because were doing SSR by default. Would have been interesting to see what would happen if you made it a client component.

  • @berlatoy
    @berlatoy Рік тому

    Thank you so much for this explanation bro

  • @yavuzselimdogan9852
    @yavuzselimdogan9852 13 днів тому

    There is also another problem: caching behaves different on localhost dev environment and production. If you solve the problem locally, still you can see cache related bugs on your prod environment.

  • @AlfonsusAC
    @AlfonsusAC Рік тому +6

    So im not the only one that is having trouble understanding this

  • @rohitsaklanimca4thsem571
    @rohitsaklanimca4thsem571 5 місяців тому

    There is still no solution about this in docs or videos . thanks to this video now I know It is not possible to invalidate the client side router cache ☺

  • @sr-juhahn
    @sr-juhahn Рік тому +1

    I feel like exactly this problem is currently ruining my mental model of authentication with nextjs. I integrated supabase, into my nextjs middleware to check if the user has a valid session before routing to protected sites and sending the user to login if not. This works great, until the user clicks 'logout' on a protected page - at which point the protected page was loaded into the client cache and after that the user is still able to access the protected page, because the nextjs link and rounter will do a soft routing and my server middleware never get's another call if the user is allowed to go to the protected page and cannot redirect.
    Tried 'force-dynamic' on the server and also tried to manually set the header 'Cache-Control: no-store' to try to convince the browser to send another request to my middleware. Any suggestions for this kind of problem?

    • @mariusespejo
      @mariusespejo  Рік тому

      They actually released new docs about the caching shortly after this video. The client-side cache that I talk about in the video is officially called “Router Cache”
      You can’t opt out of it unfortunately but they do give some options to invalidate. In your case you either need to router.refresh() on sign-out or you can use a server action to either use revalidateTag/revalidatePath (e.g. if you tagged your protected fetch calls), Or if you use cookies for auth, run cookies.delete() in a server action
      Either of those should do the trick but you’ll have to test out which one works best. If you’re trying to invalidate the server-side Data Cache in addition to the client Router Cache I think you have to use the revalidateTag/Path. Hope that helps
      nextjs.org/docs/app/building-your-application/caching#invalidation-1

  • @kaisian4940
    @kaisian4940 Рік тому

    10:37, by right you hit refresh should get the new random value already no need wait 30s

    • @shabadouwilou
      @shabadouwilou Рік тому

      thats what i was tinking but maybe i miss something

    • @mariusespejo
      @mariusespejo  Рік тому

      Yeah I now realized I made that demo more confusing lol. The point was to show that prior to waiting you see cached, after 30 seconds the number is updated. I shouldn’t have refresh, good catch!

  • @BimaAulia-fz1yt
    @BimaAulia-fz1yt 9 місяців тому

    Which next js version are you using?

    • @mariusespejo
      @mariusespejo  9 місяців тому

      Not sure what I was using here, but the github ticket for this is still open so it’s still relevant in the most recent version today

  • @j_pestana
    @j_pestana Рік тому +1

    I knew about the issue, but I haven't had any problematic situation because of it so far on the little projects I'm playing with.
    Thanks man for this huntdogs investigation work, and clarification. Great job on explaining. I really had no clue about that "Meta-caching" (Server & Client) that was going on under the hood.
    I don't see any easy fix to this though...😢
    Is there an alternative to the Link component that could help?

    • @mariusespejo
      @mariusespejo  Рік тому +3

      So to be fair I think 30s is small enough that it probably isn’t that big of a problem for most use cases. I think you can also use the native anchor tag instead of Link which would always go back to the server. Also you could manually call router.refresh() on mount … but yeah all the options are a little hacky. If the 30s (or 5min on prefetch true) doesn’t affect you then I’d just leave it. The problem is mostly for cases where you absolutely cannot get away with showing stale data

  • @LuisJimenez-uh1zx
    @LuisJimenez-uh1zx Рік тому

    Hello, I have a simple application in nextjs and mongoDB, when I'm in development it does the crud fine, but when I deploy in vercel, it's like the front doesn't refresh the data, but it does manipulate the data, I don't understand why this behavior , even so, reloading the page does not work, it is as if at the time of doing the build it saved the data from this moment and only displayed that.

    • @mariusespejo
      @mariusespejo  Рік тому

      The caching behavior for server-side only happens in prod I think, not in local. Depending on your use case you might need to set revalidate to how often you want it to, or use force-dynamic

    • @LuisJimenez-uh1zx
      @LuisJimenez-uh1zx Рік тому

      @@mariusespejo thanks

  • @bricelechatellier
    @bricelechatellier Рік тому

    Thanks for covering this in details, does this happen to layouts as well? I have a layout handling user authentication with cookies and redirecting if the user is signed in but I get into a redirect loop after signing out as it's cached on the client. Any ideas how to fix the problem?

    • @mariusespejo
      @mariusespejo  Рік тому

      Layouts do not re-render on navigation, that’s by design and is documented. You might need to force a router.refresh() in that case

    • @bricelechatellier
      @bricelechatellier Рік тому

      @@mariusespejo Thanks, makes sense, I can do a router refresh on sign out but if my session expires I’m stuck with a stale state. Looks like I’m mis-using layout and need to wrap logic in pages, correct?

    • @mariusespejo
      @mariusespejo  Рік тому

      Well in my mind you have to go to the server in some way, e.g. via a request to see if the session is still valid, and the request(s) should probably respond with maybe status 401/403. The client should then be setup to react to any request failing with that status and perhaps route to login screen and refresh

  • @tifactlong7431
    @tifactlong7431 9 місяців тому

    How about in page router? All I see is app router revalidating route but I need also it in page router

    • @mariusespejo
      @mariusespejo  9 місяців тому +1

      This caching behavior is for app router only

  • @Psych134
    @Psych134 Рік тому

    Hey buddy, as of today is there any fix from nextjs team on this issue or do we still have to use work arounds?
    Anyway, great video!

    • @mariusespejo
      @mariusespejo  Рік тому

      Not really (last I checked), there is a massive open discussion about this if you want to know where’s it at: github.com/vercel/next.js/discussions/54075
      But it really is a massive thread, but basically you still can’t configure this or opt out

    • @Psych134
      @Psych134 Рік тому

      @@mariusespejo thank you

  • @ilijanl
    @ilijanl Рік тому +2

    Great video and great explanation. I guess they do aggressive caching because of the lamda's cold starts/slow execution which makes the app slow otherwise. In my opinion caching (on every level) should always be opt-in. Something with "pre-optimisation is root of all evil"

  • @kishansripada3392
    @kishansripada3392 Рік тому

    experienced this issue myself. this clarifies so much! what's the best way right now to work around it? right before navigating to another page using router.push(), i added a router.refresh() but this doesn't seem to work.

    • @mariusespejo
      @mariusespejo  Рік тому

      You can use router.refresh() on mount of the page you’re navigating to, like in a useEffect for example. Or you can use old school html tags to force it to go back to the server
      Basically all of the solutions are hacky, hopefully they’ll provide a way to opt out. Currently the newest docs literally say you can’t opt out and people are mad haha

    • @PeterSiepen27
      @PeterSiepen27 Рік тому

      @@mariusespejo cant do router.refresh() in a server compontent tho right?

    • @mariusespejo
      @mariusespejo  Рік тому +2

      Right, it’s for client, which is where the router client cache is that we’re trying to invalidate. Btw next team did make a proposal for a fix that will let you configure the staletime but it might take them a while to implement

  • @aymenbachiri-yh2hd
    @aymenbachiri-yh2hd 3 місяці тому

    thank you for this video

  • @izumiosana
    @izumiosana Рік тому

    honestly cache revalidation is one of the hardest thing in computer science.

    • @mariusespejo
      @mariusespejo  Рік тому

      Yup but it’s even worst when you can’t opt out of it, or even control when it revalidates

  • @ibrahimo0682
    @ibrahimo0682 11 місяців тому

    just use

    • @mariusespejo
      @mariusespejo  11 місяців тому

      You can but you also lose the optimizations that the Link component provides

  • @ausername4meplease
    @ausername4meplease 10 місяців тому +1

    Thank you for the explaination but, no solution :(

  • @nikako1889
    @nikako1889 Рік тому

    is it fixed on nextjs 14?

    • @mariusespejo
      @mariusespejo  Рік тому

      Nope. You still can’t opt-out as of today. But there is an open ticket for it with a proposal from the team

    • @nikako1889
      @nikako1889 Рік тому

      @@mariusespejo thanks for answer.

  • @AshishKumar-ft6wv
    @AshishKumar-ft6wv 10 місяців тому

    😢😢 is the only option i guess

  • @shabadouwilou
    @shabadouwilou Рік тому

    why hit refresh lol

    • @mariusespejo
      @mariusespejo  Рік тому

      I just realized what you meant 😂 yeah I totally messed that up haha

  • @kumarvishalben
    @kumarvishalben Рік тому +1

    super confusing

  • @oopss794
    @oopss794 Рік тому

    many bad decisions are done in next js 13 ,

    • @mariusespejo
      @mariusespejo  Рік тому

      Give it time, community will iron it out

    • @oopss794
      @oopss794 Рік тому

      it's almost a year now since the conference

  • @felipefreire5245
    @felipefreire5245 Рік тому

    Tthis is the worst thing i have ever seen Vercel do

    • @mariusespejo
      @mariusespejo  Рік тому +1

      They did just recently comment on the github issue that they are looking at all the feedback and will address it somehow. Hopefully a better resolution in the future