fix(dev): quit command hangs/timeouts on Windows - #1532
Conversation
commit: |
CLI benchmark
Full report
|
| Setting | Value |
|---|---|
| Baseline | ref:fbc6ac038bc37503e729906f58c1f0bbf05f6d9c (v4.0.0-alpha.1) |
| Head | local packages/nuxt-cli at 736e174 (v4.0.0-alpha.1) |
| Node | v24.21.0 |
| OS | Linux 6.17.0 (kernel 6.17.0-1022-azure) |
| CPU | AMD EPYC 7763 64-Core Processor x 4 |
| Memory | 15.6 GB |
| Load average at start | 0.60, 0.19, 0.07 |
| Run started | 2026-09-10T18:29:20.898Z |
Cold CLI startup
Median of 15 interleaved runs per command, one warmup discarded.
| Command | baseline v4.0.0-alpha.1 median | head v4.0.0-alpha.1 median | Delta | baseline v4.0.0-alpha.1 min / p95 | head v4.0.0-alpha.1 min / p95 |
|---|---|---|---|---|---|
nuxt --version |
64 ms | 63 ms | -1.5% | 63 ms / 66 ms | 62 ms / 70 ms |
nuxt --version (first output byte) |
60 ms | 59 ms | -1.8% | 59 ms / 62 ms | 58 ms / 66 ms |
nuxt --help |
143 ms | 142 ms | -0.8% | 137 ms / 144 ms | 137 ms / 145 ms |
nuxt --help (first output byte) |
138 ms | 137 ms | -0.7% | 132 ms / 139 ms | 132 ms / 140 ms |
nuxt dev --help |
106 ms | 105 ms | -0.5% | 103 ms / 109 ms | 103 ms / 110 ms |
nuxt dev --help (first output byte) |
102 ms | 101 ms | -0.6% | 99 ms / 104 ms | 99 ms / 105 ms |
nuxt <unknown-command> (no-op) |
153 ms | 151 ms | -0.9% | 149 ms / 159 ms | 149 ms / 154 ms |
nuxt <unknown-command> (no-op) (first output byte) |
148 ms | 146 ms | -1.0% | 143 ms / 154 ms | 144 ms / 149 ms |
Module load cost
Counted with a module.registerHooks load hook, compile cache disabled. Counts every JS module actually evaluated on that code path (built-ins excluded, native addons excluded).
| Command | baseline v4.0.0-alpha.1 modules | head v4.0.0-alpha.1 modules | Delta | baseline v4.0.0-alpha.1 source bytes | head v4.0.0-alpha.1 source bytes | Delta |
|---|---|---|---|---|---|---|
nuxt --version |
37 | 37 | 0.0% | 302.2 kB | 302.2 kB | 0.0% |
nuxt --help |
146 | 146 | 0.0% | 1.03 MB | 1.03 MB | 0.0% |
nuxt dev --help |
81 | 81 | 0.0% | 625.1 kB | 625.1 kB | 0.0% |
Install footprint and published tarball
Each version installed on its own into an empty project with nothing but @nuxt/cli as a dependency, so the tree is exactly the CLI and its transitive dependencies. npm cache is warm and the registry is only consulted for metadata, so install wall time is indicative, not a network benchmark.
| Metric | baseline v4.0.0-alpha.1 | head v4.0.0-alpha.1 | Delta |
|---|---|---|---|
Direct dependencies of @nuxt/cli |
21 | 21 | 0.0% |
| Packages in the installed tree (unique name@version) | 35 | 35 | 0.0% |
| Unique package names | 34 | 34 | 0.0% |
| Package directories on disk (cross-check) | 29 | 29 | 0.0% |
Installed node_modules on disk |
2.49 MB | 2.49 MB | -0.0% |
| Installed files | 448 | 448 | 0.0% |
| Install wall time (warm npm cache, median of 3) | 672 ms | 668 ms | -0.6% |
| Published tarball (packed) | 286.8 kB | 286.9 kB | +0.0% |
| Published tarball (unpacked) | 989.7 kB | 989.7 kB | 0.0% |
| Files in tarball | 132 | 132 | 0.0% |
Interleaved runs on a shared runner: trust the deltas, not the absolute timings. The dev, restart and build suites run locally via pnpm bench:cli.
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #1532 +/- ##
=======================================
Coverage ? 82.86%
=======================================
Files ? 161
Lines ? 10296
Branches ? 2997
=======================================
Hits ? 8532
Misses ? 1496
Partials ? 268 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
|
Nuxt cli timeout: there is a bug at nitropack (nitro v2.13.4), when closing the worker, if there is a timeout, the caller will hang forever, in this case, nuxt cli will timeout with its default (15 seconds), missing The Patching nitropack on my local node_modules calling the |
|
Found the issue, it is a dead lock with nitropack 🥳 🥳 🥳 |
The dead lockWhen shutting down the dev server (nitro dev-server at nitropack), the process often delays for 5 seconds until it throws Root CauseThere is a deadlock between the dev worker and the parent proxy during shutdown.
This results in an infinite loop that only breaks when the parent's 5-second graceful shutdown timeout forcefully terminates the worker thread. The Fix at nitropackBy calling Changes at nitro-dev.ts shutdown async function shutdown() {
server.closeAllConnections?.();
listener?.close();
await nitroApp.hooks.callHook("close").catch(console.error);
parentPort?.postMessage({ event: "exit" });
}Applied these changes on my local: async function shutdown() {
console.log('🛑 [Worker] Shutdown started...');
server.closeAllConnections?.();
listener?.close();
await nitroApp.hooks.callHook("close").then(() => console.log('🛑 [Worker] Nitro hooks called')).catch(console.error);
console.log('🛑 [Worker] Sending "exit" event to the parent...');
parentPort?.postMessage({ event: "exit" });
}
|
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Advanced Run ID: 📒 Files selected for processing (1)
Included review availability: Your plan provides up to 2 included reviews per hour; 1 remains after this review. 📝 WalkthroughWalkthroughThe development server now tracks each WebSocket immediately after acceptance. The tracking occurs before Vite HMR filtering and Nitro upgrade handling. Each socket is removed from the tracking set when it closes, so shutdown cleanup can destroy connections that bypass request handling. Priority: ➖ Normal Estimated code review effort: 2 (Simple) | ~10 minutes Severity of issue fixed: Medium Merge Risk: ⚪ Minimal · up to The shutdown connection-tracking change has no remaining actionable risk identified. 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |



🔗 Linked issue
resolves #1531
📚 Description
This PR includes:
Maybe we can fix the deadlock here, not yet sure...