vercel / vercel/next.js

Turbopack dev server hangs all requests forever with sustained native CPU spin after its stdout pipe reader exits (`next dev | head -N`)

Open
#96,216 3 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Turbopack
Dominant language
JavaScript
Stars
142k
Forks
32.4k
Avg merge
2d 14h
Merged PRs (30d)
351

Description

Verify canary release
  • I verified that the issue exists in the latest Next.js canary release (16.3.0-canary.96)
Link to the code that reproduces this issue

https://github.com/kando19804-oss/next-turbopack-broken-pipe-hang-repro

To Reproduce
  1. pnpm install
  2. Start the dev server with an early-exiting stdout reader (bash / Git Bash):
    npx next dev -p 3111 2>&1 | head -15 &
    
  3. Request the page repeatedly:
    for i in $(seq 1 30); do curl -s -o /dev/null -m 10 -w "#$i -> %{http_code}\n" http://localhost:3111/; done
    
Current vs. Expected behavior

Current: the server works normally for the first ~11 requests (~140 ms each), then — once its cumulative log output exceeds the pipe budget (the reader's -N lines + ~64 KB pipe buffer) — every subsequent request hangs forever:

#1  -> 200
...
#11 -> 200
#12 -> 000   (curl timeout)  ← hangs forever from here
#13 -> 000
...

While frozen (measured on the minimal repro):

  • the process stays alive and keeps LISTENing; TCP connections are accepted but never answered (client sockets pile up in CLOSE_WAIT),
  • CPU time grows ~+26 s per 20 s wall clock (~1.3 cores) indefinitely while serving nothing, memory grows slowly (530 → 567 MB in 20 s),
  • a JS CPU profile (--experimental-cpu-prof, taken on a real app in the same state) shows the JS thread 99.9 % idle — the stall and the CPU burn are on the native (Turbopack) side,
  • the server never recovers; only killing the process helps.

Control: the identical server started with a file redirect instead of the pipe (npx next dev -p 3111 > dev.log 2>&1) served 1,000+ requests (cold start, 15-way parallel bursts, HMR churn) without a single failure.

Expected: anything but an unbounded silent hang + CPU spin. Either

  • keep serving requests when stdout writes fail (drop log output), or
  • fail fast with a visible error (e.g. exit on EPIPE).
Provide environment information
Operating System:
  Platform: win32
  Arch: x64
  Version: Windows 11 Pro
  Available memory (MB): 65278
  Available CPU cores: 20
Binaries:
  Node: 20.20.1
  npm: 10.8.2
  pnpm: 10.32.1
Relevant Packages:
  next: 16.2.11 (also reproduced on 16.3.0-canary.96)
  react: 19.2.3
  react-dom: 19.2.3
Next.js Config:
  output: N/A (repro), also reproduced with output: "standalone" on a large app
Which area(s) are affected? (Select all that apply)

Turbopack

Which stage(s) are affected? (Select all that apply)

next dev (local)

Additional context
  • Real-world impact: piping a dev server's output through head to capture startup logs is common in CI scripts, tmux panes, and agent/automation harnesses (pnpm dev 2>&1 | head -40 &). On a large production app this exact pattern produced "the dev server dies after ~20–30 requests" with no error output whatsoever (stdout is gone), which took us two days and a CPU profile to trace back to the launch command. The freeze threshold scales with log lines written, not requests — a browser page that fires 15 API calls reaches it in one navigation, which made it look like an app bug.
  • The repro's next.config.js sets turbopack.root only to keep workspace-root inference stable; it is unrelated.
  • If the pipe budget is exhausted during startup (e.g. | head -5, smaller than the banner), the process dies before ever listening — the pathological hang + CPU spin happens when the budget is exhausted after startup.
  • Reproduced on Windows 11 (pipe created by bash/Git Bash). The mechanism (writes to a broken/undrained stdout pipe stalling the native layer) is presumably platform-generic, but I could only verify on Windows.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the linked minimal reproduction and run npx next dev -p 3111 2>&1 | head -15, then repeat the curl requests to confirm the hang and CPU spin. Trace the next dev Turbopack stdout handling, including behavior after the pipe reader exits. Done means the server either continues serving requests or exits with a visible error instead of hanging indefinitely.

Written by the indexing model from the issue text.

Assessment

Tech stack
javascript, nextjs, node.js
Domain
backend, build-system, devtools
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
57/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.