Turbopack dev: a route handler compiled after N pages costs ~16 MB × N (50 pages + 34 handlers → 29 GB); regressed in 16.3.0-canary.101
Nobody has claimed this yet.
- Dominant language
- JavaScript
- Stars
- 142k
- Forks
- 32.4k
- Avg merge
- 2d 14h
- Merged PRs (30d)
- 351
Description
Link to the code that reproduces this issue
https://github.com/danielcizin/next-16-3-route-handler-memory-repro
To Reproduce
npm install && node gen.mjs(writes 50 trivialapp/p*/page.tsxand 34 trivialapp/api/h*/route.ts; TypeScript 5 is pinned).node drive.mjs pages-first— fresh.next, startsnext dev, GETs every page, then GETs every route handler, printing the dev server's RSS (the process listening on the port) every 10 routes.node drive.mjs handlers-first— the same with the handlers requested before the pages.
Current vs. Expected behavior
Current (next@16.3.4, also 16.3.5): after the 50 pages are compiled (~11 MB each, RSS 1.1 GB), each route handler compiled afterwards adds ~820 MB — RSS goes 1.1 → 9.2 → 17.4 → 25.7 → 29.0 GB across the 34 handlers, in 2.9 s. Requested before the pages, the same 34 handlers add ~9 MB each and the whole run ends at 1.4 GB.
The per-handler cost is linear in the number of pages already compiled: 10 pages → ~170 MB per handler, 25 → ~410 MB, 50 → ~820 MB. Removing the one shared import from the handlers (HANDLER_IMPORT=0) or from the pages (PAGE_IMPORT=0) changes nothing (28.9 GB / 27.2 GB).
Expected: a route handler's compile cost independent of how many pages were compiled before it, as in 16.2.6, where the same pages-first run ends at 2.1 GB (handlers ~9 MB each).
Bisected in the same harness (PAGES=10 HANDLERS=34, pages first; good ≈ 1 GB, bad ≈ 6.3 GB): 16.2.6, 16.3.0-canary.0/.53/.80/.93/.96/.99/.100 good; 16.3.0-canary.101 bad; 16.3.0 bad. That canary's release notes are four Turbopack server-HMR changes: #95546, #95795, #95661, #94948.
Where it bit: a CI browser matrix whose warmup requests 52 pages and then 33 route handlers of a real app killed 7 GB and 16 GB GitHub-hosted runners the moment the handlers were requested (dev server 5.9 → 8.9 → 11.7 → 14.3 GB across three handlers); reordering the warmup to handlers-first restored a 1.4 GB run. None of experimental.turbopackMemoryEviction: 'full', turbopackFileSystemCacheForDev: false, turbopackSourceMaps: false, or devMemoryThresholdRestart: false changed the peak.
Provide environment information
Operating System:
Platform: darwin
Arch: arm64
Version: Darwin Kernel Version 25.5.0: Mon Apr 27 20:41:12 PDT 2026; root:xnu-12377.121.6~2/RELEASE_ARM64_T6050
Available memory (MB): 131072
Available CPU cores: 18
Binaries:
Node: 26.0.0
npm: 11.16.0
Yarn: N/A
pnpm: N/A
Relevant Packages:
next: 16.3.4
eslint-config-next: N/A
react: 19.2.4
react-dom: 19.2.4
typescript: 5.9.3
Next.js Config:
output: N/A
Which area(s) are affected? (Select all that apply)
Turbopack, Route Handlers, Performance
Which stage(s) are affected? (Select all that apply)
next dev (local)
Additional context
Full measurement tables (both orders, three versions, the scaling series, and the bisect) are in the reproduction's README. Measured on macOS arm64 with 128 GB RAM so the run completes; on smaller machines the process is killed once the handlers start compiling. turbopackMemoryLimit (accepted by the 16.2 binding) is no longer present in 16.3's binding, so there is no bound to fall back on.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the linked reproduction, especially gen.mjs and drive.mjs, and run the pages-first and handlers-first next dev cases to confirm the memory growth. Compare the bisected boundary at 16.3.0-canary.101 with 16.2.6 and inspect the four listed Turbopack server-HMR changes (#95546, #95795, #95661, #94948). Done means route-handler compile cost no longer scales with previously compiled pages and the pages-first run has comparable memory to handlers-first.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- javascript, nextjs, react, typescript
- Domain
- build-system, performance
- Issue type
- Bug
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100