Next.js Memory Leak: Fetch + Standalone Mode — 2 Years Without a Fix
Next.js patches global fetch and adds a cache layer that leaks memory on every request. In Docker/K8s this causes OOM crashes every few hours. The bug exists since Next.js 14 and is still unresolved in 16.2.x.
TL;DR
Next.js patches the global fetch and adds a cache layer that holds references to response data after they should have been freed. Every fetch call adds memory that is never returned to GC. In Docker/Kubernetes this leads to OOM crashes every few hours. The bug has existed since Next.js 14 (April 2024) and is still unresolved in 16.2.x (March 2026). On Vercel the problem doesn't manifest due to ephemeral serverless functions.
How Normal Fetch Works
Request → fetch → got data → response to user → GC cleans up → memory freeHow Fetch Works in Next.js
Next.js intercepts the global fetch and wraps it with its own cache/tracking layer:
Request → Next.js fetch wrapper → creates:
- Performance entry (speed tracking) ← not cleaned
- Request metadata object ← not cleaned
- Internal promise wrapper ← not cleaned
- Cache lookup entry ← not cleaned
- Response body (for unique URL) ← not cleaned
→ Response to user
→ GC sees objects are still referenced → doesn't touch them
→ Memory grows indefinitelyWhat Happens in Production
Self-hosted (Docker/K8s):
Request 1: fetch → +100KB → RAM: 100KB
Request 2: fetch → +100KB → RAM: 200KB
Request 1000: fetch → +100KB → RAM: 100MB
Request 50,000: fetch → +100KB → RAM: 5GB → OOM Kill 💀
→ Kubernetes restarts the pod → cycle repeats
Vercel (Serverless):
Request 1: [start] → fetch → +100KB → [process dies] → 0 KB ✅
Request 2: [start] → fetch → +100KB → [process dies] → 0 KB ✅
→ Memory never accumulatesAffected Versions
Next.js — All Versions with App Router
| Version | Issue | Date |
|---|---|---|
| 14.2.x | #64212 | April 2024 |
| 14.x-15.x | #68578 | August 2024 |
| 14.3.0-canary | #79588 | May 2025 |
| 16.0.1 | #85914 | November 2025 |
| 16.1.0 | #88603 | January 2026 |
| 16.0.10 | #90433 | February 2026 |
| 16.2.0-canary.51 | Confirmed in #90433 comments | March 2026 |
Node.js
Tested on Node.js 20, 22, 24, 25 — leaks on all of them.
What Doesn't Work
| Attempt | Result |
|---|---|
cacheMaxMemorySize: 0 | Doesn't help — leak is not from this cache |
| Disable image optimization | Doesn't help |
--max-old-space-size=6144 | Just crashes slower |
Read response via .json() / .text() | Doesn't help |
| Remove React fetch patching (canary.45) | Doesn't help |
| Upgrade to latest version | Doesn't help (leaks on 16.2.0-canary.51 too) |
What Works (Workarounds)
| Workaround | Why it helps |
|---|---|
Replace fetch with axios | Bypasses Next.js wrapper |
Replace fetch with node-fetch | Same reason |
| Downgrade Node.js to 20.15.1 | Older undici has fewer leaks (for some) |
Docker image node:20-alpine3.21 | Helps in some cases |
| Deploy to Lambda (SST + OpenNext) | Ephemeral functions — memory doesn't accumulate |
| Deploy to Vercel | Same — serverless |
Axios Workaround Limitation
Your own API calls can be replaced with axios. But Next.js internally uses the patched fetch for:
- ISR (Incremental Static Regeneration)
revalidatePath/revalidateTag- Server Components data fetching with deduplication
use cache(Next.js 16)
Even without a single fetch in your code — Next.js still uses it under the hood.
Why Vercel Doesn't Fix It
Business Logic
Vercel is a company that makes money hosting Next.js. On their platform the problem doesn't manifest (serverless = ephemeral). The bug only affects self-hosted (Docker, K8s, VPS) — those who don't pay Vercel.
Official Position
Tim Neutkens (Vercel maintainer) analyzed the issue and declared it a problem with undici (Node.js fetch library), not Next.js. Issue #90433 was closed. Despite the fact that:
- axios and node-fetch on the same Node.js work without leaks
- The leak only appears when fetch goes through the Next.js wrapper
- The bug has been open for 2 years without a fix
Priorities
In these 2 years the Next.js team shipped:
- Turbopack (2-5x faster builds) — marketing advantage
- Cache Components /
use cache— reduces load on Vercel servers proxy.tsinstead of middleware — simplifies edge deployment on Vercel- DevTools MCP — AI hype
Memory leak in self-hosted? Not a priority.
Solution: AWS Lambda (SST + OpenNext)
What Is It
OpenNext is an open-source adapter that converts a Next.js build into a format for AWS Lambda. SST is a framework that automates the infrastructure.
Architecture
Next.js build
→ OpenNext
→ AWS Lambda (SSR, API routes)
→ S3 (static, assets)
→ CloudFront (CDN)
→ SQS + DynamoDB (ISR revalidation)Why This Solves the Memory Leak
Lambda functions process requests and are recycled after 5-15 minutes of inactivity. Memory doesn't have time to accumulate.
Deploy
npx sst@latest init
npx sst deploy --stage productionComparison
| Vercel | AWS Lambda (SST) | Docker self-hosted | |
|---|---|---|---|
| Memory leak | Not felt | Not felt | Critical |
| Cold starts | Yes | Yes (~200-500ms) | No |
| Price (~medium traffic) | $20-150/mo | $5-30/mo | $5-50/mo |
| Control | Minimal | Full | Full |
| ISR/Revalidation | Works | Works (SQS) | Works (with leak) |
| Vendor lock-in | Vercel | AWS | None |
Lambda Nuances
- Cold starts — first request is slower (~200-500ms)
- Security — enable OAC (Origin Access Control), otherwise Lambda URL is public
- OpenNext — community project, not official Vercel. New Next.js features may break
- Wallet attack — during DDoS, Lambda auto-scaling can lead to a large bill
Why a Real Fix Is Unrealistic
1. Architectural Problem
The leak is not an accidental bug but a consequence of a design decision: Next.js intercepts the global fetch and adds cache/tracking on top. To fix it — the way App Router interacts with fetch needs to be redesigned. This affects ISR, revalidation, data cache, request deduplication — the framework's core.
2. Conflict of Interest
Vercel is not motivated to fix what doesn't affect their platform. Self-hosted competes with their business. The more problems in self-hosted — the more people migrate to Vercel.
3. Blame Shifting
The official position is "it's undici, not us". Until this changes — they won't work on a fix.
4. No Community Fix
Next.js AGPL-3.0 license allows forks, but the codebase is massive and tightly coupled with Vercel infrastructure. A community PR to fix the fetch wrapper would require deep understanding of the internal architecture and approval from maintainers — who already closed the issue.
Conclusions
- If on Vercel — no problem, nothing to do
- If self-hosted and need serverless — SST + OpenNext on AWS Lambda
- If self-hosted Docker — replace fetch with axios where possible, monitor RAM, set up automatic pod restarts
- If starting a new project — consider SvelteKit or Nuxt as alternatives without this problem
Sources
- Issue #64212 — Memory Leak with global fetch (April 2024)
- Issue #68578 — Possible memory leak in Fetch API (August 2024)
- Issue #85914 — Memory Leak with fetch + standalone (November 2025)
- Issue #90433 — OOM in 16.0.10 (February 2026)
- Discussion #88603 — OOM in Docker/K8s (January 2026)
- Discussion #88078 — cacheMaxMemorySize behavior
- OpenNext
- SST — Next.js on AWS
- Secret knowledge to self-host Next.js
- Next.js Memory Usage Guide