Skip to content

[turbopack] On-demand memory report for the dev server#96086

Draft
lukesandberg wants to merge 4 commits into
canaryfrom
audit_retained_tasks
Draft

[turbopack] On-demand memory report for the dev server#96086
lukesandberg wants to merge 4 commits into
canaryfrom
audit_retained_tasks

Conversation

@lukesandberg

@lukesandberg lukesandberg commented Jul 22, 2026

Copy link
Copy Markdown
Contributor

What?

Adds an on-demand memory report for the Turbopack dev server. While next dev is running you can ask the backend what it is holding in memory, without restarting or attaching an external profiler:

  • HTTP: GET /__nextjs_turbopack-memory?format=json|markdown
  • CLI: next internal turbopack-memory [--format json|markdown] [--url <devServerUrl>]

The report enumerates every cell of every task and groups it by value type, ranked by strong_count — the number of live triomphe::Arc references to the cell's data, a cheap and real proxy for retention. It is split into two sections:

  • Transient — tasks eviction skips entirely (where per-route/per-request accumulation shows up). For the top types it also includes a sample dependency chain so you can see which computation is holding the data.
  • Persistent — cells that survived eviction (unevictable cells, or tasks blocked from eviction).

The JSON is additionally augmented with Node process stats (RSS, heap, pid, uptime) by the dev-server layer.

Why?

We needed a way to diagnose what Turbopack retains after eviction on a live dev server.

This supersedes #90271, which is the original attempt at this feature. That PR estimated per-item memory via bincode encode-and-discard, which both over- and under-counts badly (it ignores reference-counted structures like RcStr/Rope and doesn't account for hash-table slack). It was also ~2000 commits behind canary and predated the backend refactor. This PR keeps that PR's delivery mechanism (NAPI binding → HTTP endpoint → CLI, JSON + markdown) but drops the size estimation entirely in favor of the strong-count / transient-vs-persistent breakdown, which is derived from the existing Storage::audit_all_cells instrumentation on this branch. #90271 is being closed in favor of this one.

How?

  • Rust (turbo-tasks-backend): TurboTasksBackend::collect_memory_report() builds a structured MemoryReport { transient, persistent } from audit_all_cells(), reusing debug_trace_transient_task for the transient sample chains. The previous behavior — dumping a text report to /tmp on every eviction cycle — has been removed; the report is now on-demand only.
  • NAPI: project_get_memory_report exposes it as projectGetMemoryReport (runs on a blocking thread since it walks all tasks).
  • Dev server: getMemoryReportMiddleware serves the endpoint and renders the markdown; wired into the Turbopack hot-reloader middleware chain.
  • CLI: next internal turbopack-memory discovers the running dev server from the .next lock file (or --url) and prints the report.
  • Docs + e2e test added; error 1423 registered for the failure path.

This is a dev-only diagnostic tool, so no telemetry is added.

Closes PACK-6917
Supersedes #90271

Copy link
Copy Markdown
Contributor Author

This stack of pull requests is managed by Graphite. Learn more about stacking.

@lukesandberg lukesandberg changed the title lru audit data [turbopack] On-demand memory report for the dev server Jul 22, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant