Skip to main content
← Tilbage til bloggen
Next.jsMemory LeakDockerAWS LambdaNode.js

Next.js Memory Leak: Fetch + Standalone-tilstand — 2 år uden fix

Next.js patcher den globale fetch og tilføjer et cache-lag, der lækker hukommelse ved hver anmodning. I Docker/K8s fører dette til OOM-nedbrud hver par timer. Buggen har eksisteret siden Next.js 14 og er stadig uløst i 16.2.x.

Udgivet 19. marts 202610 min læsning

TL;DR

Next.js patcher den globale fetch og tilføjer et cache-lag, der holder referencer til responsdata, efter de burde have været frigivet. Hvert fetch-kald tilføjer hukommelse, der aldrig returneres til GC. I Docker/Kubernetes fører dette til OOM-nedbrud hver par timer. Buggen har eksisteret siden Next.js 14 (april 2024) og er stadig uløst i 16.2.x (marts 2026). På Vercel viser problemet sig ikke takket være efemere serverless-funktioner.

Hvordan normal fetch fungerer

Request → fetch → got data → response to user → GC cleans up → memory free

Hvordan fetch fungerer i Next.js

Next.js opfanger den globale fetch og pakker den ind med sit eget cache-/tracking-lag:

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

Hvad der sker 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

Berørte versioner

Next.js — Alle 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

Testet på Node.js 20, 22, 24, 25 — lækker på alle.

Hvad der ikke virker

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)

Hvad der virker (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

Dine egne API-kald kan erstattes med axios. Men Next.js bruger internt den patchede fetch til:

  • ISR (Incremental Static Regeneration)
  • revalidatePath / revalidateTag
  • Server Components data fetching med deduplikering
  • use cache (Next.js 16)

Selv uden en eneste fetch i din kode — bruger Next.js den stadig internt.

Hvorfor Vercel ikke fikser det

Forretningslogik

Vercel er en virksomhed, der tjener penge på at hoste Next.js. På deres platform viser problemet sig ikke (serverless = efemert). Buggen påvirker kun self-hosted (Docker, K8s, VPS) — dem, der ikke betaler Vercel.

Officiel position

Tim Neutkens (Vercel-maintainer) analyserede problemet og erklærede det for et undici-problem (Node.js fetch-bibliotek), ikke Next.js. Issue #90433 blev lukket. På trods af at:

  • axios og node-fetch på samme Node.js fungerer uden lækager
  • Lækagen kun opstår, når fetch går gennem Next.js-wrapperen
  • Buggen har været åben i 2 år uden en fix

Prioriteringer

I løbet af disse 2 år har Next.js-teamet udgivet:

  • Turbopack (2-5x hurtigere builds) — markedsføringsfordel
  • Cache Components / use cache — reducerer belastningen på Vercel-servere
  • proxy.ts i stedet for middleware — forenkler edge-deployment på Vercel
  • DevTools MCP — AI-hype

Memory leak i self-hosted? Ikke en prioritet.

Løsning: AWS Lambda (SST + OpenNext)

Hvad er det

OpenNext er en open-source-adapter, der konverterer et Next.js-build til et format til AWS Lambda. SST er et framework, der automatiserer infrastrukturen.

Arkitektur

Next.js build
  → OpenNext
    → AWS Lambda (SSR, API routes)
    → S3 (static, assets)
    → CloudFront (CDN)
    → SQS + DynamoDB (ISR revalidation)

Hvorfor dette løser hukommelseslækagen

Lambda-funktioner behandler anmodninger og genbruges efter 5-15 minutters inaktivitet. Hukommelsen når ikke at akkumulere.

Deployment

npx sst@latest init
npx sst deploy --stage production

Sammenligning

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-nuancer

  • Cold starts — første anmodning er langsommere (~200-500ms)
  • Sikkerhed — aktiver OAC (Origin Access Control), ellers er Lambda-URL'en offentlig
  • OpenNext — community-projekt, ikke officielt fra Vercel. Nye Next.js-funktioner kan gå i stykker
  • Tegnebogsangreb — ved DDoS kan Lambda auto-scaling føre til en stor regning

Hvorfor en rigtig fix er urealistisk

1. Arkitekturproblem

Lækagen er ikke en tilfældig bug, men en konsekvens af en designbeslutning: Next.js opfanger den globale fetch og tilføjer cache/tracking ovenpå. For at fixe det skal måden, App Router interagerer med fetch, redesignes. Dette påvirker ISR, revalidation, data cache, request deduplication — frameworkets kerne.

2. Interessekonflikt

Vercel er ikke motiveret til at fixe det, der ikke påvirker deres platform. Self-hosted konkurrerer med deres forretning. Jo flere problemer i self-hosted — jo flere migrerer til Vercel.

3. Skyldforskydning

Den officielle position er "det er undici, ikke os". Indtil det ændrer sig — vil de ikke arbejde på en fix.

4. Ingen community-fix

Next.js AGPL-3.0-licens tillader forks, men kodebasen er enorm og tæt koblet til Vercel-infrastrukturen. En community-PR til at fixe fetch-wrapperen ville kræve dyb forståelse af den interne arkitektur og godkendelse fra maintainers — som allerede har lukket issuen.

Konklusioner

  1. Hvis du er på Vercel — intet problem, intet at gøre
  2. Hvis self-hosted og behov for serverless — SST + OpenNext på AWS Lambda
  3. Hvis self-hosted Docker — erstat fetch med axios hvor muligt, overvåg RAM, konfigurer automatisk pod-genstart
  4. Hvis du starter et nyt projekt — overvej SvelteKit eller Nuxt som alternativer uden dette problem

Kilder