next.js: App router deduping not working as expected
Verify canary release
- I verified that the issue exists in the latest Next.js canary release
Provide environment information
Operating System:
Platform: darwin
Arch: x64
Version: Darwin Kernel Version 22.3.0: Mon Jan 30 20:42:11 PST 2023; root:xnu-8792.81.3~2/RELEASE_X86_64
Binaries:
Node: 16.13.0
npm: 9.6.4
Yarn: N/A
pnpm: N/A
Relevant packages:
next: 13.4.7
eslint-config-next: 13.4.7
react: 18.2.0
react-dom: 18.2.0
typescript: 5.1.6
Which area(s) of Next.js are affected? (leave empty if unsure)
No response
Link to the code that reproduces this issue or a replay of the bug
https://github.com/richie-south/nextjs-cache
To Reproduce
Clone the provided repo, run commands, check terminal logs for both api and next.
- start api server
npm run api
- start next
npm run dev
Describe the Bug
Next will make multiple fetch requests to the same path on page reload even if docs says they should be deduped.
This happens on dev and production deployment.
if i reload the root page /
i can see in my api logs that it will makes 3 request to my api, having fetch in my RootLayout and generateMetadata.
If i make a reload on other pages, ex /todo
in my provided example, i will get 5 api requests for the same path.
Expected Behavior
I expect the requests to be deduped as illustrated in the docs. So instead of up to 5 requests it should be 1 when no cache is available.
Which browser are you using? (if relevant)
No response
How are you deploying your application? (if relevant)
Other platform
About this issue
- Original URL
- State: open
- Created a year ago
- Reactions: 31
- Comments: 32 (2 by maintainers)
Isn’t this a massive issue? I’m kinda confused how everyone is experiencing this and nobody seems to be talking about the fact that deduping doesn’t really work…
Yes, I think the docs are very clear, it’s not meant to de-dup across different URLs.
The problem is that it doesn’t actually work. Posting another repo with 14.1.4, the problem is still there: https://codesandbox.io/p/devbox/next-double-fetch-mcfppg
This is still happening on 13.4.16 btw, and is causing large performance and costs for people not aware it is happening.
@zwarunek We got around this issue by manually wrapping every fetch with the cache function documentation.
The docs say requests are memoized only when the URL and options are identical.
I cannot reproduce this issue anymore with next 14.1.0 and my example project. Would be great if someone else wants to try, otherwise i will close this in the future. 😃
@OlegLustenko
Docks👆
Docs says that dedupe works only if you use native fetch which Next.js extends. So yeah I’m personally experiencing things with pure fetch and didn’t expect the same from libraries. And if you want to get this with third-party libraries it is recommended to use
cache
function.You can wrap the API requests with React.cache instead.
https://react.dev/reference/react/cache
I tried this on your codesandbox and it returns the same timestamp twice, and only sends the API request once, as you expected.
https://github.com/vercel/next.js/blob/218d0709eb97017e5bbd55f603bce033206bf71e/packages/next/src/server/lib/patch-fetch.ts#L501-L504
Hi @ztanner ! (author of incremental-cache at #53030) I’m trying to solve this issue with @rjsdnql123 . We have question about
lock()
on incremental-cache!On
patch-fetch.ts#L502
, request try to lock incremental-cache first. When incremental-cache is empty and multiple requests with same url(cacheKey) comes in, these requests can get lock incremental-cache at the same time?https://github.com/vercel/next.js/blob/218d0709eb97017e5bbd55f603bce033206bf71e/packages/next/src/server/lib/incremental-cache/index.ts#L241-L252
On above code, I think
createLockIfAbsent
logic is not synchronized over multiple requests so maybe multiple requests can create lock at the same time? 🤔Has this been resolved? I tried to reproduce the issue, but it appears that the server request is only occurring once in reality.