-
Notifications
You must be signed in to change notification settings - Fork 27.2k
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
Memory Leak with Next.js's global fetch. Tested against http module #64212
Comments
This comment has been minimized.
This comment has been minimized.
@m-rphy interesting! I've a question about the charts with next.js's global fetch. What is the cause of the halt in the memory consumption? You've stopped the process or it's the garbage collector? |
We switched to using axios for request handling instead of the native fetch. That's it. These charts, produced by Grafana for our production environment, illustrate the severity of the memory leak issue we faced. Our application, which processes thousands of outgoing requests per second, suffered significantly due to this memory leak. This repository is capable of reproducing the memory leak, as well as bypassing it by simply changing the HTTP handler. While we use axios in our production app, in this repo's toy model, I implemented a simple "fetch" with Node.js' http module. However, the effect remains the same. If you by pass next.js fetch and use one that implement node's http module, the leak goes away. |
@m-rphy Thanks for the explanations!! I'll switch then to axios. |
How did you switch them to Axios for Apollo Client in NextJS? |
We are using cross-fetch and it works much better. |
I don't see how are you going not to "use fetch" on a custom watered down javascript runtime, aka edge. Axios wraps either |
You're absolutely right. Maybe I'm wrong but I say for lambdas running on nodejs runtime I could replace Next.js's fetch for axios/cross-fetch/... to have a significant gain. For edge lambda I will either stick to global fetch or move them to nodejs runtime with non global fetch. |
hey folks, we think we identified the source of the leak, we'll try to fix it by next week |
This comment has been minimized.
This comment has been minimized.
We're still investigating! |
Anyone have a work around besides using cross-fetch ? |
@m-rphy in your screenshot, are the graph drops due to a server restart? What I can see for now is that there's some fetch data being collected as part of the performance observer metrics, but I think those get flushed, and some others we're collecting that is being retained. |
Yes. The server is running in kubernetes and the service is restarted when resources are starved. |
If I use Cross-fetch in Apollo Client to response time (doing 10 calls) reduces from 1.5 seconds to .5 seconds consistently. Apollo Client I believe uses fetch() that is in NextJS right? Like this: import fetch from 'cross-fetch';
|
This ensures we only track fetch metrics in development mode as that's the only time we report them currently, this also adds an upper limit on how many metrics we store per-request as previously this was unbounded, on top of that this ensures we don't keep tracking fetch metrics after the request has ended as we only report on request end, and finally this adds a clean-up to the reference we attach to the request object containing the fetch metrics once we have used them. Closes: #64212 Closes NEXT-3159
Hi, this has been updated in |
Looks like it's working well! I've only tested in the toy app, but we'll port the fetching back to the native fetch and do some testing in the production application. |
This ensures we only track fetch metrics in development mode as that's the only time we report them currently, this also adds an upper limit on how many metrics we store per-request as previously this was unbounded, on top of that this ensures we don't keep tracking fetch metrics after the request has ended as we only report on request end, and finally this adds a clean-up to the reference we attach to the request object containing the fetch metrics once we have used them. Closes: #64212 Closes NEXT-3159
This has also been released in v14.2.3. Seems to resolve the memory issue 🚀 , but unfortunately we still had to switch to cross-env because of #64956 |
I still face |
@RashmikaFeefo if you upgraded and are still facing the issue it's most likely unrelated to fetch at this point and you might have a user code memory leak. Investigating via |
I've used 14.2.3 and not v14.3.0-canary.11. And yeah I already tried node --inspect but didn't find any code issues. I've called several async APIs using fetch in a server component (api/[directory]/page.tsx) and facing this issue in prod. |
@RashmikaFeefo please open a new issue with a minimal reproduction and we can take a closer look, although without further info there isn't much we can investigate on our end. |
This closed issue has been automatically locked because it had no new activity for 2 weeks. If you are running into a similar issue, please create a new issue with the steps to reproduce. Thank you. |
Link to the code that reproduces this issue
https://github.com/m-rphy/nextMemoryLeak
To Reproduce
In one terminal and
cd
into the/express_server
and runnpm start
In a sperate teminal
cd
in/next_app
and runnpm run inspect
Using any browser go to either
http://localhost:3000/start-fetch
orhttp://localhost:3000/start-custom-fetch
to begin the requests.Then open chrome inspect (
chrome://inspect
) or use any other debugging tools.I believe this is ticket is also relevant - but this repo reproduces it with and avoids it -> #54708
Current vs. Expected behavior
Next.js's global fetch is holding onto performance metrics or some other data that is leading to heap growth after every requests.
The heap should not grow after the scope closes.
Provide environment information
Operating System: Platform: darwin Arch: arm64 Version: Darwin Kernel Version 23.4.0: Fri Mar 15 00:12:49 PDT 2024; root:xnu-10063.101.17~1/RELEASE_ARM64_T6020 Available memory (MB): 16384 Available CPU cores: 10 Binaries: Node: 20.10.0 npm: 10.2.3 Yarn: N/A pnpm: N/A Relevant Packages: next: 14.2.0-canary.62 // Latest available version is detected (14.2.0-canary.62). eslint-config-next: 14.1.4 react: 18.2.0 react-dom: 18.2.0 typescript: 5.4.4 Next.js Config: output: N/A
Which area(s) are affected? (Select all that apply)
Not sure, Data fetching (gS(S)P, getInitialProps)
Which stage(s) are affected? (Select all that apply)
next dev (local), next build (local), next start (local), Other (Deployed)
Additional context
I've tested this repo against different canary releases (canary-32 and canary-62), as well as Next.js lts.
I haven't been able to find a version that works.
The text was updated successfully, but these errors were encountered: