Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unclear caching behavior in nextjs 14 and 15 #71881

Open
mastoj opened this issue Oct 25, 2024 · 3 comments
Open

Unclear caching behavior in nextjs 14 and 15 #71881

mastoj opened this issue Oct 25, 2024 · 3 comments
Labels
bug Issue was opened via the bug report template.

Comments

@mastoj
Copy link
Contributor

mastoj commented Oct 25, 2024

Link to the code that reproduces this issue

https://github.com/mastoj/wrapped-fetch-debug

To Reproduce

I have the exact same app in nextjs 14: https://github.com/mastoj/wrapped-fetch-bug-14 and nextjs 15: https://github.com/mastoj/wrapped-fetch-debug

What we are doing is testing what is happening when you wrap fetch in a higher order function, since that is a natural way to componse functions together.

Both of the solution is not behaving as I expect them to. To reproduce the issue in any of the repos do:

  1. pnpm run build
  2. pnpm run start
  3. http://localhost:3000/debug
  4. http://localhost:3000/debug

Current vs. Expected behavior

Doing the first load will print the logs from the api/route:

==> Getting some data: /api/data/1
==> Getting some data: /api/data/2
==> Getting some data: /api/data/3

which is as expected. Doing the second load of the page is what makes things interesting. In our /debug page we are making three api-calls in a slightly different way, but I expect them all to be cached.

Nextjs 14 behavior

For some reason the fetch call that is wrapped using a higher order function won't cache at all and we get the following output:

==> Getting some data: /api/data/2

Nextjs 15 behavior

In 15 the behavior differed quite a lot from 14. To some degree it make sense since the defaults has changed. Since we are using explicit const dynamic and revalidate on fetch I would actually expect the behavior to be the same, but that is not the case. In 15 it seems like nothing is cached and we make api calls every time.

==> Getting some data: /api/data/1
==> Getting some data: /api/data/2
==> Getting some data: /api/data/3

Expected behavior

Even though we have export const dynamic = "force-dynamic" I would expect the revalidate on the fetch calls to be honored. That assumptions means I would expect no outputs from the log from the routes to be outputted since no calls should be made.

Provide environment information

Operating System:
  Platform: darwin
  Arch: arm64
  Version: Darwin Kernel Version 23.6.0: Mon Jul 29 21:13:04 PDT 2024; root:xnu-10063.141.2~1/RELEASE_ARM64_T6020
  Available memory (MB): 65536
  Available CPU cores: 12
Binaries:
  Node: 20.14.0
  npm: 10.7.0
  Yarn: 1.22.22
  pnpm: 9.9.0
Relevant Packages:
  next: 14.2.8 // An outdated version detected (latest is 15.0.1), upgrade is highly recommended!
  eslint-config-next: 14.2.8
  react: 18.3.1
  react-dom: 18.3.1
  typescript: 5.6.3
Next.js Config:
  output: N/A
 ⚠ An outdated version detected (latest is 15.0.1), upgrade is highly recommended!
   Please try the latest canary version (`npm install next@canary`) to confirm the issue still exists before creating a new issue.
   Read more - https://nextjs.org/docs/messages/opening-an-issue

Which area(s) are affected? (Select all that apply)

Not sure

Which stage(s) are affected? (Select all that apply)

next start (local), Vercel (Deployed)

Additional context

I have verified the behavior both locally and on vercel.

@mastoj mastoj added the bug Issue was opened via the bug report template. label Oct 25, 2024
@gruckion
Copy link

Typo. “ For some reason the fetch call that is wrapped using a higher order function want cache at all and we get the following output:”.

won’t cache**

@gruckion
Copy link

gruckion commented Oct 25, 2024

Force dynamic is used to ensure that the request is generated at request time. It is not used for caching.

https://nextjs.org/docs/app/api-reference/file-conventions/route-segment-config#dynamic

As for using revalidate in the fetch request. You are not using the ‘cache’ attribute as well. Which in NextJS 15 defaults to no store.

https://nextjs.org/docs/app/api-reference/functions/fetch

So you will need to set that if you want the fetch request to be cached.

Note the docs say:

As a convenience, it is not necessary to set the cache option if revalidate is set to a number.

But I believe this is only true for NextJS 14. Please try setting ‘“cache”: “force-cache”,’ and try again if you are using NextJS 15.

You can read more about this change here.

https://nextjs.org/blog/next-15
https://nextjs.org/blog/next-15-rc

image

@mastoj
Copy link
Contributor Author

mastoj commented Oct 25, 2024

(fixed typo)

Added cache: "force-cache" with no difference in behavior: mastoj/wrapped-fetch-debug@dff943b

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Issue was opened via the bug report template.
Projects
None yet
Development

No branches or pull requests

2 participants