#yes that cache does not invalidate nor
1 messages · Page 1 of 1 (latest)
In that case, why Next Documentation is mentioning the revalidation?
or did I get it wrong?
different cache
that example uses 2 separate cache
cache() to dedupe function
and revalidate = 3600 will cache the build result of layout/page (called the full router cache in this case)
what's the purpose of the react cache in this scenario than?
to dedupe the calls
getItem might be called multiple times in separate server components
its job is to dedupe it and made sure its only get called once
So this will be cached like forever and will not update, correct?
getItem with react cache
no it wont be cached forever
it only dedupe calls in a single request
so if I request to server for /dashboard
and dashboard has 3 server components <A/> <B/> <C/> each calls getItem it will only call getItem once and not thrice
if I call /dashboard again, then it will call getItem once again.
if I request /dashboard again, then it will call getItem once again
assuming the /dashboard route is not cached
this 'works' for me but absoltuely not the cleanest and im sure it can be improved. just wanted to show a working example
import prisma from '@/db/prisma';
import { unstable_cache } from 'next/cache';
//Types go here
const getCachedExercises = unstable_cache(
async () => {
//Check to see when the db is actually being queried
console.log("Fetching exercises from the database");
return await prisma.exercise.findMany();
},
['exerciseList'],
{
tags: ['exercises'], //revalidate on demand if needed
revalidate: 30000, // revalidate after 30 seconds otherwise
}
);
export default async function getExercises(): Promise<Exercise[]> {
return await getCachedExercises();
}
this however, unstable_cache, will cache the result for the next request
so it persists data in between requests
but there are many ways to persists data in between request
depending how you want to cache stuff
I was looking at unstable_cache today and thinking about to give it a try. Do you think it's suitable for production of simple one page website?
to be honest i can't tell unless you tell me what do you want to cache and what for
coz i dont know the use case
The scenario I want to achieve is that I want to cache prisma results and revalidate it once a day. I know my data does not change very often and if it changes it does not has to be reflected immedieately on the frontend
just prisma cache results? what prisma cache result? how many component will use the prisma result? is it just being used in a single component or will it be reusable in other component or places?
for me when im using unstable_cache the main issue is dealing with cached user data. i've been trying out so many things but ultimately i had to remove all caching on user data becuase it gets impractical with large user base. unstable_cache is perfect for caching prisma fetches that arent user specific imo
whats the problem with cached user data?
@edgy trout so for caching non user specific data is it ok?
we actually spoke about it a while back. In a situation where you are doing a prisma find 'where: userId' that needs to be revalidated by a tag that includes the userId you'd end up with tonnes of individual caches, say you have a bunch of Models and thousands of users.
i dont know where the cache is stored or how its maintained but i had to remove it from a prod app because it was having memory issues, it did work but im not sure how to manage all that cache. i think we said using redis was a better solution
i think its stored in the memory
i have a slight suspicion that its stored in the memory
because the memory gets persisted in Serverless Function
both in dev and prod
i use it on any prisma fetch that istn user specific andworks like a dream. i had a massive performance boost and reduced my db interactions by like 100x
while doing research i saw people saying their unstable_cache was getting mixed up and returning the wrong data but that seems to be user specific caches
https://3int.uk/ This is my website. It's served on Digital Ocean App Platform. It's my first app created using next and starting point for more complex projects I am planning to do. So every section is a dynamic component and it is being generated from a mongo collection. However the structure will rarely change so it should be cached. Also navbar component is making same call for that collection as it composes dynamically hash links. Than every content in sections is being stored in collections as well so again I'd like these to be cached and revalidate them like once a day
this is what i think too, but there is v little docs on unstable_cache so im doing what i can until we see a stable version.
sick animation! is that framer? sorry unrelated
well i assumed it works just like fetch() cache since both are considered as Data Cache
@edgy trout am not sure if am following, but is it possible, that what you are talking about might be actually an issue I am experiencing - when my app is up for 3 days it goes out of memory and actually navbar an dymanic section components returns an error when I click on any menu link
yes it is
Wont you consider caching the page instead of the prisma function result?
correct me if im wrong but since you dont have user accounts, couldnt you statically generate the whole site?
and use a webhook to revalidate the cache when you make changes so you dont have to rebuild
I'd do anything you tell me is good for my scenario. I am just totally lost in this caching situation and am not any clever from documentation.
can you run npm run build and show us your build output?
just sec
i would assume it would be statically build by default, but it sounds like ssr
When I start this project I was trying to do statically generated site, but at some point I failed and I don't remember now why. I am using app router and am not sure if it was related to it.
hmm... we can see your main page is statically generated which is very confusing if you're having memory issues.
/legal/[slug] should be ssg imo not ssr
and what is that client async error about? cant you do the fetch in a server component and pass it to the client component?
I'll update the legal, that's the latest thing I was doing. However it also works preperly when app's out of memory.
it does look like a memory leak based on your graph
the hero is my bad it's async but also client
i would fix it but tbh it shouldnt even matter since the page is fully built at build time
yes and given the cached prisma results are returning error I think it might be related to it
you shouldnt need any prisma cache
since the only time it will query your db is when you run build
after that its justa fully rendered static page
Ok, I'll revert all the cache. However before using cache any time I did a change in my collection it was reflected on frontend which technically should be if statically generated, correct?
i assumed so, maybe @storm zealot can shed some more light on the situation
if you make the legal route ssg then i cant imagine any reason you would get memory leaks
it could be static too but with ssg you have the option to revalidate it without rebuilding which is nice if you plan to add more posts
yes this is actually what I want. However am experiecning memory leak since my first deployement with no prisma caching. I read somewhere thet next will consume all dedicated memory over time and it does not do cleanup, but also it should not affect the application.
for example in my portfolio site:
Route (app)
┌ ○ /
├ ○ /_not-found 0 B 0 B
├ λ /api/disable-draft 0 B 0 B
├ λ /api/draft 0 B 0 B
├ λ /api/revalidate 0 B 0 B
├ ○ /apple-icon.png 0 B 0 B
├ ○ /projects
├ ● /projects/[slug]
├ ├ /projects/redacted
├ ├ /projects/redacted
├ ├ /projects/redacted
├ └ [+6 more paths]
├ ○ /tech-stack
├ ● /tech-stack/[slug]
├ ├ /tech-stack/redacted
├ ├ /tech-stack/redacted
├ ├ /tech-stack/redacted
├ └ [+11 more paths]
└ ○ /terms
everything is static or ssg but i have some api routes to handle revalidating and other things
so when i make a new post a webhook revalidates the cache for me immediately
could you share that revalidation api? or at least some external resource which is explaning this part ?
cause that's actually what I'd like to implement
sure thing:
import { NextRequest, NextResponse } from 'next/server'
import { revalidateTag } from 'next/cache'
export async function POST(request: NextRequest) {
const requestHeaders = new Headers(request.headers)
const secret = requestHeaders.get('x-vercel-reval-key')
if (secret !== process.env.CONTENTFUL_REVALIDATE_SECRET) {
return NextResponse.json({ message: 'Invalid secret' }, { status: 401 })
}
revalidateTag('posts')
return NextResponse.json({ revalidated: true, now: Date.now() })
}
it has some stuff specific to the contentful cms and making it secure but otherwise pretty straightforward
this is pretty common for next and headless cms
you could for example get github to fire the webhook when you push to your main branch
in my example the cms fires the webhook whenever i add or change a post
the one drawback being if i make a new post i will have to rebuild or it will be served up dynamically
essentially its just an api route that will call revalidateTag, you could use revalidatePath too but i wanted it to be more granular
Great you just answered what I was planning to ask about. So revalidatePath on root will just revalidate everything, right?
You are using revalidateTag, can look up at documentation, but since you are here, where and how have you specified this tag in your code?
i have no experience with projects deployed other than in Vercel 😭
Sorry to @ you. I just didn’t want to be giving out incorrect advice lol
I’m no expert with revalidate path but I guess the page would have to be ssg not static for that work either way
But essentially all that will happen is will retrigger all of your server component fetches
So tag might be a more efficient approach
Regarding your memory leak I have absolutely no idea why that is happening
But if you remove SSR from the equation it will make it a lot easier to debug imo
I had to move to Heroku from Vercel as my app did not behave properly on Vercel, links didn't work as expected, database reached 200MB limit with 50kb content, everyhting I tried went wrong. No issues on heroku though. Then I moved to Digital Ocean and other than memory leaks, still everything works fine
I had the db issues with vercel too idk why. I use supabase and host the site on a VPS with apache now. Something I want to revisit. Would use vercel if they supported IPV6 for domains
Ok, I'll revert the changes and will look on other points we have discussed and will see if this will fix the memory leak as well.
Feel free to dm me if you get stuck. Or make a help post and tag me
I’m a noob but working with nextjs all day every day trying to understand the intricacies
awesome, you've been a great help to me, really appreciate it. Sometimes I just need some others views to get out of my thinking box. The worst thing is when I just stick with documentation and in the end find out, that I didn't understand it at all. Thanks mate
My pleasure. Your site looks amazing btw great job on the design
Once you get these minor issues out the way it will be perfect
thanks it's quite funny you are saying so as Design is my biggest nightmare and I hate it so much. I'd love to write frontend, backend but god please no design.
haha me too. i often fallback on ui libs but im trying to go pure tailwind at the moment and make my own, its hard
yeah, same here. But still it's total drawback when you are trying to write a functionality and than stuck on frontend cause you don't like the look. Definetely worst thing for people with ADHD 😄
absolutely, as a fellow sufferer i love to get the back and front end working and do it fast. then i spend a month adjusting margins and padding back and forth with no real progression 😄
😄 damn, I'm so happy to see there's more people out there having same silly problems :D. Thanks again
Hey guys, I am gonna continue in this thread as it is easier to follow up.
I was playing a bit with my code and I find out, that caching works actually fine with or without react/cache applied, BUT for some reason it does not work for components in layout.
In my root level layout I've applied 'force-static' and revalidation to 60 seconds (my previous problem was I was using math not exact number, which according to documentation is not supported). Suddenly everything works fine, all my pages are statically generated and revalidates every 60s or on-demand using @edgy trout's API example. However in that layout I have components Navbar and Footer which do access DB as well (to dynamically compose links) and data for these components seems not to be cached. Everytime I hit hard refresh I can see a call to DB for each component. If I comment these components out, these extra calls disappears.
Any idea, why is this happening? I've attached a screenshot - Yellow line is hard refresh, Red line is hard refresh after revalidation call
i'll have a look this evening when i get a chance, looks like you're on the right track. Considering the nature of the site have you considered hard coding the navbar and footer? I know its not a solution but as i remember the navbar is quite simple?
Yeah that's definetely a way to avoid this issue. However I'd like to know also a dynamic solution, as this is a starting point for my next project. I've used this simple website only to learn how Next works
thats fair, i'll have a think about it and get back to you this evening after work. Maybe its my lack of understanding but i would assume if "/" is being built/rendered as 'static' then there should be no fetching done in the file? since all of the fetching and building happens as build time
Interestingly If I move the Navbar from the root Layout to root page, it stops re-rendering on hard refresh.
Hi @edgy trout . I've seen in the chat last week you've been asking about sharp library and as we have discussed memory leak in my prod environment as well I just decided to let you briefly know, that I've solved my memory leak today and it was related to the sharp. Apparently it does not work happely in standard linux distributions. There are some tips in Sharps documentation how to fix that, but for me the easiest way was to deploy my app to container running Alpine linux instead of DO App Platform's Ubuntu. So just in case you'd experience something similar this might be the core issue.