Next.js Memory Leak: Fetch + Standalone-läge — 2 år utan fix
Next.js patchar den globala fetch och lägger till ett cache-lager som läcker minne vid varje förfrågan. I Docker/K8s leder detta till OOM-krascher var några timmar. Buggen har funnits sedan Next.js 14 och är fortfarande olöst i 16.2.x.
TL;DR
Next.js patchar den globala fetch och lägger till ett cache-lager som håller referenser till svarsdata efter att de borde ha frigjorts. Varje fetch-anrop lägger till minne som aldrig returneras till GC. I Docker/Kubernetes leder detta till OOM-krascher var några timmar. Buggen har funnits sedan Next.js 14 (april 2024) och är fortfarande olöst i 16.2.x (mars 2026). På Vercel visar sig problemet inte tack vare efemära serverless-funktioner.
Hur normal fetch fungerar
Request → fetch → got data → response to user → GC cleans up → memory freeHur fetch fungerar i Next.js
Next.js fångar upp den globala fetch och omsluter den med sitt eget cache-/tracking-lager:
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 indefinitelyVad som händer i produktion
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 accumulatesDrabbade versioner
Next.js — Alla versioner med 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
Testat på Node.js 20, 22, 24, 25 — läcker på alla.
Vad som inte fungerar
| 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) |
Vad som fungerar (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 |
Begränsning med axios-workaround
Dina egna API-anrop kan ersättas med axios. Men Next.js använder internt den patchade fetch för:
- ISR (Incremental Static Regeneration)
revalidatePath/revalidateTag- Server Components data fetching med deduplicering
use cache(Next.js 16)
Även utan en enda fetch i din kod — använder Next.js det fortfarande internt.
Varför Vercel inte fixar det
Affärslogik
Vercel är ett företag som tjänar pengar på att hosta Next.js. På deras plattform visar sig problemet inte (serverless = efemärt). Buggen påverkar bara self-hosted (Docker, K8s, VPS) — de som inte betalar Vercel.
Officiell position
Tim Neutkens (Vercel-maintainer) analyserade problemet och förklarade att det är ett undici-problem (Node.js fetch-bibliotek), inte Next.js. Issue #90433 stängdes. Trots att:
- axios och node-fetch på samma Node.js fungerar utan läckor
- Läckan bara uppstår när fetch går genom Next.js-wrappern
- Buggen har varit öppen i 2 år utan fix
Prioriteringar
Under dessa 2 år har Next.js-teamet släppt:
- Turbopack (2-5x snabbare builds) — marknadsföringsfördel
- Cache Components /
use cache— minskar belastningen på Vercel-servrar proxy.tsistället för middleware — förenklar edge-deployment på Vercel- DevTools MCP — AI-hype
Memory leak i self-hosted? Inte en prioritet.
Lösning: AWS Lambda (SST + OpenNext)
Vad är det
OpenNext är en open-source-adapter som konverterar en Next.js-build till ett format för AWS Lambda. SST är ett ramverk som automatiserar infrastrukturen.
Arkitektur
Next.js build
→ OpenNext
→ AWS Lambda (SSR, API routes)
→ S3 (static, assets)
→ CloudFront (CDN)
→ SQS + DynamoDB (ISR revalidation)Varför detta löser minnesläckan
Lambda-funktioner bearbetar förfrågningar och återvinns efter 5-15 minuters inaktivitet. Minnet hinner inte ackumuleras.
Deployment
npx sst@latest init
npx sst deploy --stage productionJämförelse
| 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-nyanser
- Cold starts — första förfrågan är långsammare (~200-500ms)
- Säkerhet — aktivera OAC (Origin Access Control), annars är Lambda-URL:en publik
- OpenNext — community-projekt, inte officiellt från Vercel. Nya Next.js-funktioner kan gå sönder
- Plånboksattack — vid DDoS kan Lambda auto-scaling leda till en stor faktura
Varför en riktig fix är orealistisk
1. Arkitekturproblem
Läckan är inte en slumpmässig bugg utan en konsekvens av ett designbeslut: Next.js fångar upp den globala fetch och lägger till cache/tracking ovanpå. För att fixa det behöver sättet App Router interagerar med fetch designas om. Detta påverkar ISR, revalidation, data cache, request deduplication — ramverkets kärna.
2. Intressekonflikt
Vercel är inte motiverat att fixa det som inte påverkar deras plattform. Self-hosted konkurrerar med deras affär. Ju fler problem i self-hosted — desto fler migrerar till Vercel.
3. Skuldförskjutning
Den officiella positionen är "det är undici, inte vi". Tills det ändras — kommer de inte arbeta på en fix.
4. Ingen community-fix
Next.js AGPL-3.0-licens tillåter forks, men kodbasen är enorm och tätt kopplad till Vercel-infrastrukturen. En community-PR för att fixa fetch-wrappern skulle kräva djup förståelse av den interna arkitekturen och godkännande från maintainers — som redan stängt issuen.
Slutsatser
- Om du är på Vercel — inget problem, inget att göra
- Om self-hosted och behöver serverless — SST + OpenNext på AWS Lambda
- Om self-hosted Docker — ersätt fetch med axios där det är möjligt, övervaka RAM, konfigurera automatisk pod-omstart
- Om du startar ett nytt projekt — överväg SvelteKit eller Nuxt som alternativ utan detta problem
Källor
- 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