Skip to main content
← Tillbaka till bloggen
Next.jsMemory LeakDockerAWS LambdaNode.js

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.

Publicerad 19 mars 202610 min läsning

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 free

Hur 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 indefinitely

Vad 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 accumulates

Drabbade versioner

Next.js — Alla versioner med App Router

VersionIssueDate
14.2.x#64212April 2024
14.x-15.x#68578August 2024
14.3.0-canary#79588May 2025
16.0.1#85914November 2025
16.1.0#88603January 2026
16.0.10#90433February 2026
16.2.0-canary.51Confirmed in #90433 commentsMarch 2026

Node.js

Testat på Node.js 20, 22, 24, 25 — läcker på alla.

Vad som inte fungerar

AttemptResult
cacheMaxMemorySize: 0Doesn't help — leak is not from this cache
Disable image optimizationDoesn't help
--max-old-space-size=6144Just crashes slower
Read response via .json() / .text()Doesn't help
Remove React fetch patching (canary.45)Doesn't help
Upgrade to latest versionDoesn't help (leaks on 16.2.0-canary.51 too)

Vad som fungerar (workarounds)

WorkaroundWhy it helps
Replace fetch with axiosBypasses Next.js wrapper
Replace fetch with node-fetchSame reason
Downgrade Node.js to 20.15.1Older undici has fewer leaks (for some)
Docker image node:20-alpine3.21Helps in some cases
Deploy to Lambda (SST + OpenNext)Ephemeral functions — memory doesn't accumulate
Deploy to VercelSame — 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.ts istä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 production

Jämförelse

VercelAWS Lambda (SST)Docker self-hosted
Memory leakNot feltNot feltCritical
Cold startsYesYes (~200-500ms)No
Price (~medium traffic)$20-150/mo$5-30/mo$5-50/mo
ControlMinimalFullFull
ISR/RevalidationWorksWorks (SQS)Works (with leak)
Vendor lock-inVercelAWSNone

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

  1. Om du är på Vercel — inget problem, inget att göra
  2. Om self-hosted och behöver serverless — SST + OpenNext på AWS Lambda
  3. Om self-hosted Docker — ersätt fetch med axios där det är möjligt, övervaka RAM, konfigurera automatisk pod-omstart
  4. Om du startar ett nytt projekt — överväg SvelteKit eller Nuxt som alternativ utan detta problem

Källor