Node.js 26.7.0 Adds Perfetto Tracing Support
Node.js 26.7.0 landed on August 5, 2026, and buried in the Notable Changes list is a line of just three words: add perfetto support (#64565). It reads like a footnote. It is actually a rebuild of one of the platform's oldest and least loved subsystems — the tracing layer.
The problem: trace output from another era
For years, built-in tracing in Node.js has worked like this:
node --trace-event-categories v8,node,node.async_hooks server.jsThe result is a file named node_trace.1.log. Despite the extension, its contents are JSON in Chrome's legacy Trace Event Format. The format is entirely textual, so files balloon under any realistic load, and the traditional viewer — chrome://tracing — is effectively abandoned tooling.
The bigger issue is no longer convenience. The discussion in nodejs/diagnostics#654 laid out that V8, which produces a large share of the trace data Node emits — GC, compilation, execution — is moving to Perfetto exclusively and dropping the legacy tracing mechanism. Since V8 sits at the core of Node.js, the options were to follow it or to gradually lose the richest data source the runtime has.
What changed
Release 26.7.0 introduces a new tracing backend built on the Perfetto SDK, enabled at build time:
./configure --with-perfetto
make -j"$(nproc)"After that, usage is unchanged — same flags, same categories:
node --trace-event-categories node.perf,node.async_hooks,v8 \
--trace-event-file-pattern '${pid}-${rotation}.pftrace' \
server.jsThe difference is the output. Instead of JSON, Node writes a protobuf-encoded file named node_trace.1.pftrace, which opens directly in ui.perfetto.dev. And that viewer offers more than a timeline: Perfetto exposes a SQL query layer over the trace, so the data can be interrogated rather than scrolled through.
The programmatic API is untouched as well:
import { createTracing } from 'node:trace_events';
const tracing = createTracing({
categories: ['node.perf', 'v8'],
});
tracing.enable();
// the work being measured
await handleRequest(req);
tracing.disable();That is deliberate design. The swap happens underneath; the surface developers already know stays where it was. The categories are unchanged too — node.perf for Performance API measurements, node.async_hooks for async operations, node.fs.sync and node.fs.async for file system calls, v8 for engine data. What changed is where those events end up and in what encoding, not how they are collected.
Caveats worth stating plainly
- Not enabled in official builds.
--with-perfettois aconfigure-time option, which means today's official binaries do not include it. In practice that means a custom build, or waiting on a decision to enable it by default. - No JSON output in this mode. The exclusion is intentional. Any in-house tooling that reads
node_trace.*.logand parses it as JSON needs a different path. - Inspector tracing is disabled. With Perfetto active, the NodeTracing domain over the inspector is turned off, because the protocol needs raw bytes delivered rather than protocol objects.
- No backport. The change is scoped to 26.x and will not land on 22.x or 24.x — and 26.x is Current, not LTS.
Takeaway
Observability keeps moving from something bolted on afterwards to something the runtime owns. A queryable protobuf trace is not merely a tidier format than JSON; it is data that tooling understands, and that the coding agents now taking part in performance triage understand as well. The gap between scrolling a several-hundred-megabyte JSON file and running a SQL query against the same data is the gap between slow manual reading and a structured investigation.
Today the step is still a build option, but the direction is clear: the tracing path in Node.js is being reassembled to speak the same language as the rest of the ecosystem's tooling. Anyone who followed what shipped in Node.js 26.6 will notice that the 26.x line carries structural change rather than surface polish.
Primary source: the Node.js 26.7.0 release notes, with implementation detail in PR #64565.