Next.js Discord

Discord Forum

Next.js Server Action Triggered from Client Component Causing Multiple Identical API Calls

Unanswered
Snowshoe posted this in #help-forum
Open in Discord
SnowshoeOP
I’m using Next.js 15, and I have a client component that triggers a server action when the user types into an input. The server action internally calls a fetch() with next: { revalidate: 3600 }.

Even though the input value (slug) is the same and I debounce the call, I’m seeing multiple identical fetches to the same external API within seconds — all from different IPs (likely due to serverless cold starts). I expect deduplication to prevent this, but it's not happening for this one API.

All other server actions behave as expected and don’t duplicate calls.
Why doesn’t deduplication or caching work in this case, even with next.revalidate?

15 Replies

If you want to get data, the best approach is to make a utility function and wrap it in unstable_cache, set the cache tags and revalidation times in there and now you can call this cached function directly in your server components to fetch data. You could also call the same function in route handlers in case you need to fetch data directly from a client component.
Original message was deleted
SnowshoeOP
It can not run in paralell ON THE CLIENT, right?
Yes they’re basically meant to be used on the Client.
Otherwise, the question is: why would you want to run them on the server if you’re already on the server?
@LuisLl Yes they’re basically meant to be used on the Client. Otherwise, the question is: why would you want to run them on the server if you’re already on the server?
SnowshoeOP
Does the client POST call opt out of unstable cache? Or why do we need a route handler?
No, nothing can’t opt out of unstabke_cache (as far as I know), but you can revalidate it. Once you wrap your function in unstable_cache, the only way to clear the cache is by calling a revalidation strategy on that specific tag or path, or setting a revalidation time on the specific function.

What I said about route handlers was in case you needed to fetch data from the client and you can’t pass the data down from a server component to the client component, what you would have done (not saying you should) is calling a server action from a client component, but since server actions should NOT be used to fetch data, we need to call a route handler. For POST, server actions are fine (they’re a POST endpoint under the hood)
SnowshoeOP
Yeah but when I called the server action from a client it sent a POST and I think it opted out of the cache. So when we send instead a GET to a route handler and the route handler calls the same server action than the cache should work. Or am i missing something?
I did not mean it invalidates the unstable cache but it created a new entry IMO
POST requests are never cached by default, but if you wrap them in unstable cache they will be cached too.
You shouldn’t call a server action from a route handler, just make the function an regular utility function and call it from your route handler instead.
AFAIK in next15 GET Route Handler aren’t cached by default anymore.
SnowshoeOP
I have a server action that i want to use both on client and server side. Its wrapped in unstable cache. When i called from server it works as expected. But when I call from client it always calls the api and not the cache. This is why i created a route handler that i call from the client and the route handler calls the same server action
so i made this since i need a GET to get data and not POST to mutate
Instead of calling the server action from your route handler you can abstract that logic into a reusable utility function, agnostic to route handlers or server actions, and then you can call the same function in both places.

And that’s how you should do it, GET to get data, POST for mutations.