tokio-rs/console: a task-level debugger for async Rust
a debugger for async rust!
At a glance
- What is it?
- The tokio-rs/console repository ships a gRPC wire protocol, a tracing-subscriber Layer that instruments Tokio applications, and an interactive CLI for inspecting tasks. It is aimed at Rust engineers debugging async runtimes, and it requires a tokio_unstable build to collect task data.
- Who is it for?
- Adopt tokio-rs/console if you run Tokio and need to see which tasks are alive, what they are polling, and where they stall; the console-subscriber Layer plus the tokio-console CLI is the intended path. Skip it if you cannot rebuild with tokio_unstable, if your tracing setup uses compile-time filters, or if you need production-grade always-on profiling rather than a debugger.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 53 days ago.
- What is it written in?
- Mainly Rust, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 27, 2026, and from our analysis. They are not legal advice.
Editorial analysis
What tokio-rs/console solves for Tokio applications
An async Rust program does not fail the way a threaded one does. Tasks are cheap, numerous, and scheduled by the runtime, so a stalled future looks like nothing at all in a stack trace. The repository exists to make that invisible layer observable. The README describes the project as "a diagnostics and debugging tool for asynchronous Rust programs" and compares the task list view to "top(1) for tasks." The audience is narrow and specific: teams running Tokio who need to know which tasks exist, what state they are in, and which ones are not making progress. If your program is single-threaded, synchronous, or does not use Tokio, none of the three components in this repository applies to you.
Three components and the gRPC path between them
The toolkit splits into a producer, a wire format, and a consumer. The wire format is defined with gRPC and protocol buffers, and the console-api crate holds generated code for projects using the tonic gRPC implementation. The protobuf definitions live under console-api/proto, and the README notes that projects using other gRPC code generators, including those in other languages, can depend on the definitions directly. That is a deliberate design choice: the data producer and the data viewer are decoupled, so a graphical or web-based client is possible without touching the instrumentation side. On the producer side, console-subscriber implements the instrumentation API as a tracing-subscriber Layer. On the consumer side, tokio-console is an interactive command-line tool that acts as a gRPC client. Data flows from the instrumented process, over the wire protocol, into whatever client connects.
Instrumenting a Tokio program with console_subscriber::init()
The README gives a one-liner for the top of main. Add the console-subscriber crate as a dependency first, then call the initializer. Note that the README shows the call without a surrounding main function, so the exact placement is up to your program.
console_subscriber::init();The build must enable the tokio_unstable cfg, otherwise task data is not collected. The README offers two ways to do this. The first is an environment variable at build time.
RUSTFLAGS="--cfg tokio_unstable" cargo buildThe second is a persistent setting in .cargo/config.toml, which is easier to keep consistent across a team.
[build]
rustflags = ["--cfg", "tokio_unstable"]One more condition matters. The tokio and runtime tracing targets must be enabled at the TRACE level. The README states that console_subscriber::init() and the console_subscriber::Builder APIs enable these targets automatically. If you configure tracing manually with EnvFilter or Targets, you must add "tokio=trace,runtime=trace" to the filter. The README also warns against enabling any of the compile-time filter features in Cargo.toml, because those would strip the events before the subscriber sees them.
Running the tokio-console CLI against a live process
Install the CLI from crates.io. The README gives the command with the --locked flag.
cargo install --locked tokio-consoleThen run it locally with no arguments. By default it attempts to connect to an instrumented application on localhost port 6669.
tokio-consoleIf the application runs elsewhere, pass a target address as an argument, either as <IP>:<PORT> or <DNS_NAME>:<PORT>. The README's example uses a URL form.
cargo run -- http://my.great.console.app.local:5555For a local checkout of the repository, the README lists cargo run as an alternative to installing the binary. The CLI also supports additional flags; tokio-console --help prints them, and one subcommand, gen-config, generates a console.toml config file with the default configuration. The README does not document the contents of that generated file, so treat the subcommand as the source of truth rather than guessing at keys.
The tokio_unstable requirement is the real adoption cost
The most consequential constraint is not in the CLI, it is in the build. Task data from Tokio is only collected when tokio_unstable is enabled, which means the binary you debug is not the binary you ship unless you ship with that cfg too. Nightly-only or unstable cfg flags tend to get excluded from release pipelines for good reason, so in practice this is a development and staging tool. Two other failure modes are easy to hit. A manually configured tracing subscriber that omits the tokio and runtime targets at TRACE will produce an instrumented process that reports nothing useful, and the README explicitly calls this out. Compile-time filter features in Cargo.toml cause the same silent emptiness. Neither problem produces an obvious error at the console; you connect and see little. Finally, if you need always-on profiling in production with low overhead, this is the wrong category of tool: it is a debugger you attach when investigating, not a continuous metrics pipeline.
How tokio-console differs from a sampling profiler
A sampling profiler answers "where is CPU time going" by interrupting the process at intervals and recording stacks. tokio-rs/console answers a different question: "what tasks exist right now, and which are stuck." The mechanism is instrumentation, not sampling. The console-subscriber Layer subscribes to tracing events emitted by the Tokio runtime and forwards them over gRPC to a connected client. That distinction has practical consequences. An instrumented build reports task state continuously and in detail, including tasks that are idle and consuming no CPU, which a sampler would never see. It also means the data only exists if the process was built with the instrumentation and the right cfg in the first place. With a profiler you can attach to an unmodified binary; with tokio-rs/console you cannot. The README also frames the project's lineage as part of a broader effort on async Rust debugging, referencing pprof, top(1), htop(1) and XCode Instruments as antecedents, which places it in the interactive-inspection family rather than the profiling family.
Maintenance, releases and the MIT licence
The repository is not archived, and the last push was on 2026-08-08, roughly six weeks before this writing. The most recent releases are tokio-console-v0.1.14, console-subscriber-v0.5.0 and console-api-v0.9.0, all published on 2025-10-30. The three crates version independently, which matters when you pin dependencies: console-subscriber and console-api are separate artifacts, and the wire protocol between them is defined by protobuf, so a mismatch between producer and consumer versions is a real upgrade consideration. The repository uses release-plz.toml and cliff.toml, which indicates automated release and changelog tooling, and the workspace members are tokio-console, console-subscriber, console-api and xtask. The licence is MIT. In practical terms that permits commercial and closed-source use with the usual requirement to carry the notice, but the repository's LICENSE file is the authoritative text and this is not legal advice. Because the instrumentation ships inside your binary, the licence of the crates you link is the one that follows your build, not a separate server licence.
Editorial conclusion
Adopt tokio-rs/console if you run Tokio and need to see which tasks are alive, what they are polling, and where they stall; the console-subscriber Layer plus the tokio-console CLI is the intended path. Skip it if you cannot rebuild with tokio_unstable, if your tracing setup uses compile-time filters, or if you need production-grade always-on profiling rather than a debugger. Before wiring it in, confirm that your .cargo/config.toml carries the rustflags entry, that the tokio and runtime targets reach TRACE, and that port 6669 is reachable from where you run the CLI.
Frequently asked questions
What is tokio-rs/console used for?
It is a diagnostics and debugging tool for asynchronous Rust programs. The repository contains a gRPC wire protocol, the console-subscriber instrumentation Layer for Tokio, and the tokio-console interactive command-line viewer.
Why does tokio-rs/console require tokio_unstable?
The README states that collecting task data from Tokio requires the tokio_unstable cfg to be enabled. You can set it with RUSTFLAGS="--cfg tokio_unstable" at build time or by adding a rustflags entry to .cargo/config.toml.
Which port does the tokio-console CLI connect to by default?
By default it attempts to connect to an instrumented application running on localhost on port 6669. A different address can be passed as an argument in <IP>:<PORT> or <DNS_NAME>:<PORT> form.
How do I install the tokio-console command-line tool?
The README gives cargo install --locked tokio-console to install it from crates.io. Alternatively, from a local checkout of the repository, the README lists cargo run as an alternative method.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/tokio-rs-console)