correct ways to cache user-specific data in Next.js with Clerk and an external backend?
I’m working on a Next.js app with authentication handled through Clerk. The authentication is done server-side.
The current flow is:
The user signs up or logs in with Clerk.
After the first login, they go through an onboarding flow where they need to provide some additional information.
This information is not just basic user data that I can get from Clerk. It’s app-specific data that the application needs later.
After onboarding, the user gets access to the actual dashboard/application.
Most of my app logic is server-side. For every request at this state (I'm at the very start of the project), not only mutations but also GET requests, I have a server-side function in Next.js that calls my external backend, and that backend returns the data I need.
My main confusion is around caching.
A lot of this information does not change very often. For example, the user’s profile data or the information collected during onboarding is updated rarely. The mental model I was trying to use is something like this:
* I create a server-side function that fetches the user data from my external backend.
* I cache that function or that request in Next.js.
* Whenever a page needs the user data, it just calls that function.
* If the data is already cached, I avoid another call to my backend.
* When the user updates their data through a form, I invalidate the cache.
* The next time the data is needed, it gets fetched again from the backend and cached again.
In theory, this felt like a way to avoid client-side state management for data that is already available server-side and does not change frequently. But I’m not sure if this approach is correct, if it’s an anti-pattern, or if I’m missing something important.
I also have a few related doubts.
Clerk seems to verify the user every time I visit a page. But if the user has already authenticated once, shouldn’t it be enough to have a token with an expiration time and only verify the user again when that token expires? Or is it normal for this verification to happen frequently on the server side?
Also, does it make sense to use Server Actions for GET requests? Since I have an external backend, I’m wondering whether it makes sense to cache things in Next.js, or whether caching should be handled directly in the backend instead, for example with Redis.
Overall, I’m pretty confused about how I should think about caching in this setup. I want to avoid unnecessary backend calls when I know certain data rarely changes, but I also don’t want to build something fragile or conceptually wrong.
What is the correct way to handle this kind of data in a Next.js app with Clerk, an external backend, and mostly server-side logic?