Parallel Fetch requests are not cached in vercel upon deployment
Unanswered
Bearded Collie posted this in #help-forum
Bearded CollieOP
Following Nextjs 13's docs on fetch cache: https://nextjs.org/docs/app/building-your-application/data-fetching/fetching-caching-and-revalidating#caching-data
I expect all fetch calls response to be cached and cached responses should be relatively faster. In our project, on local machine caching works as expected, we get sub-millisecond response for cached calls, however we noticed that some of our fetch calls are not being in cached on deployment even when they are explicitly set to be cached. On further exploration we found that if we invoke fetch in parallel inside a async-await loop, the fetch is not cached.
For sake of example i have used cdn urls of cdnjs and jsdelivr and fetched them in parallel, and also a singular api fetch call without loop. I have attached the screenshots of response times. (code in next reply)
It might be something silly in the code or something wrong on vercel's end (probably not) i am not sure. This behaviour isn't document either in the docs. Any help would be greatly appreciated.
EDIT:
We are using "nextjs":"13.4.13"
I expect all fetch calls response to be cached and cached responses should be relatively faster. In our project, on local machine caching works as expected, we get sub-millisecond response for cached calls, however we noticed that some of our fetch calls are not being in cached on deployment even when they are explicitly set to be cached. On further exploration we found that if we invoke fetch in parallel inside a async-await loop, the fetch is not cached.
For sake of example i have used cdn urls of cdnjs and jsdelivr and fetched them in parallel, and also a singular api fetch call without loop. I have attached the screenshots of response times. (code in next reply)
It might be something silly in the code or something wrong on vercel's end (probably not) i am not sure. This behaviour isn't document either in the docs. Any help would be greatly appreciated.
EDIT:
We are using "nextjs":"13.4.13"
5 Replies
Bearded CollieOP
Here's the code i have used:
async function benchmark(fn: Promise<any>) {
const start = performance.now();
const response = await fn;
const end = performance.now();
return {
ts: `${formatDecimal(end - start, 'en', 3)} ms`,
output: response,
};
}
async function fetchGroup(cache: 'force-cache' | 'no-store', files: any): Promise<any> {
const requests = files.map(async (file: any) => {
const ts = await benchmark(
fetch(file.url, {
cache: cache,
next: {
tags: ['tag'],
},
}).then((response) => response.text()),
);
return `${file.namespace}: ${ts.ts}`;
});
return Promise.all(requests);
}
const groupBUrls = [
{
namespace: 'react',
url: 'https://cdnjs.cloudflare.com/ajax/libs/react/18.2.0/cjs/react-jsx-dev-runtime.development.js',
},
{
namespace: 'react-router',
url: 'https://cdnjs.cloudflare.com/ajax/libs/react-router/6.15.0/react-router.development.js',
},
{
namespace: 'react-is',
url: 'https://cdnjs.cloudflare.com/ajax/libs/react-is/18.2.0/cjs/react-is.development.js',
},
{
namespace: 'jquery',
url: 'https://cdn.jsdelivr.net/npm/jquery@3.7.0/dist/jquery.min.js',
},
{
namespace: 'slick-carousel',
url: 'https://cdn.jsdelivr.net/npm/slick-carousel@1.8.1/slick/slick.min.js',
},
];any build errors?
Bearded CollieOP
@aardani Here's a reproduction project => https://github.com/i-am-mani/next-13-failing-fetch-cache-reproduction
And the preview URLs:
1) no-store - always hit the remote => https://next-13-failing-fetch-cache-reproduction.vercel.app/?cache=no-store
2) force-cache - once cached returned previous response => https://next-13-failing-fetch-cache-reproduction.vercel.app/?cache=force-cache
Play around the options a bit you'll realise that fetch call for single API is cached correctly as noted by big drop in response time from say 30ms to 5-10ms, however same is not try to for parallel API calls, sometimes i get faster response with no-store than force-cache.
This is a strange behavious because i would expect under 10ms response time even for fetch API requests that are made in parallel, however that's not true upon deployment.
In local development the parallel API calls are cached as noted by their huge drop in response time from 100s to >1ms, this fails to hold on deployment.
Is my code flawed or is my understanding on the subject has some holes. Shouldn't vercel cache fetch responses irrespective of how they are invoked?
And the preview URLs:
1) no-store - always hit the remote => https://next-13-failing-fetch-cache-reproduction.vercel.app/?cache=no-store
2) force-cache - once cached returned previous response => https://next-13-failing-fetch-cache-reproduction.vercel.app/?cache=force-cache
Play around the options a bit you'll realise that fetch call for single API is cached correctly as noted by big drop in response time from say 30ms to 5-10ms, however same is not try to for parallel API calls, sometimes i get faster response with no-store than force-cache.
This is a strange behavious because i would expect under 10ms response time even for fetch API requests that are made in parallel, however that's not true upon deployment.
In local development the parallel API calls are cached as noted by their huge drop in response time from 100s to >1ms, this fails to hold on deployment.
Is my code flawed or is my understanding on the subject has some holes. Shouldn't vercel cache fetch responses irrespective of how they are invoked?
Bearded CollieOP
@aardani sorry for pinging again, any thoughts on this?
No, i have no clue whats going on