Skip to content
FunCoding

hotpath_init

Configure hotpath profiling in a Rust project. Adds the hotpath dependency with feature-gated setup, instruments main with hotpath::main, functions with measure/measure_all, and wraps channels, mutexes, rw_locks, streams, futures, reqwest clients, axum routers and byte-level I/O with hotpath macros. Use when the user wants to add or set up hotpath profiling in a crate.

Star
1,878
License
MIT
Last commit
Oct 12, 2026

skills/hotpath_init/SKILL.md

View on GitHub

Initialize hotpath Profiling

Set up hotpath profiling in the current Rust project. The setup is fully feature-gated: zero compile-time and runtime overhead unless the hotpath feature is explicitly enabled. All macros are noops when the feature is off, so no cfg_attr wrapping is needed.

Documentation

The hotpath docs are the reference for every macro, cargo feature, parameter and caveat; this skill only holds the procedure. Every page of https://hotpath.rs is served as markdown when requested with an Accept: text/markdown header:

curl -sL -H 'Accept: text/markdown' https://hotpath.rs/functions

Before each step, fetch the pages it names and follow them instead of relying on memory. Keep -L (some pages redirect) and the header (there are no .md URLs). A #fragment is not sent to the server: fetch the whole page and find the heading. Fetch a page only when the project uses what it covers.

The site documents the latest hotpath release, which can be newer than the version the project uses. Never change the project's hotpath version because the docs show a newer one. If the docs describe something that version does not have, tell the user it needs a newer hotpath instead of working around it.

PageCovers
https://hotpath.rs/basic setup, example report
https://hotpath.rs/profiling_modes#[hotpath::main] vs HotpathGuardBuilder, report options, TUI, optional vs non-optional dependency
https://hotpath.rs/functionsmain, measure, measure_all, skip, measure_block!, allocation profiling, custom allocators
https://hotpath.rs/data_flowchannel!, stream!, future!: supported libraries and their cargo features, hotpath::wrap:: types, call-site aggregation, capacity
https://hotpath.rs/locksmutex!, rw_lock!: supported libraries and their cargo features, wrapped types
https://hotpath.rs/io_tracingio!, io_unwrap, measured layers, compression encoders
https://hotpath.rs/sql_tracingsqlx, Diesel and Toasty query profiling
https://hotpath.rs/http_tracingreqwest and ureq client profiling
https://hotpath.rs/axum_tracingaxum router profiling, route scoping of SQL and HTTP
https://hotpath.rs/tokio_runtimetokio_runtime!() metrics
https://hotpath.rs/configurationevery environment variable
https://hotpath.rs/regression_policythe policy file of step 7

Steps

1. Inspect the project

  • Find the binary crate(s) and the main function. If there is no main you control (e.g. a library or a test harness), use the HotpathGuardBuilder API instead of #[hotpath::main] (see step 3).
  • Detect the async runtime (tokio, smol, none) and which instrumentable primitives the code uses: channels, Mutex and RwLock, futures streams, SQL (sqlx, diesel, toasty), HTTP clients (reqwest, ureq; note the major version), axum routers (find where the Router is finished and passed to axum::serve), byte-level I/O values implementing std::io::Read/Write or tokio::io::AsyncRead/AsyncWrite (files, sockets, compression codecs).
  • Fetch the docs pages of what you found. They list the supported libraries and versions; skip a primitive the docs do not support.

2. Add the dependency and feature passthrough

In the target crate's Cargo.toml:

[dependencies]
hotpath = "0.28"

[features]
hotpath = ["hotpath/hotpath"]
hotpath-alloc = ["hotpath/hotpath-alloc"]
hotpath-prometheus = ["hotpath/hotpath-prometheus"]
hotpath-cloud = ["hotpath/hotpath-cloud"]

Enable the extra hotpath cargo features on the dependency (tokio, a channel or lock library, an SQL or HTTP integration, ...) that the pages fetched in step 1 name for the primitives the project uses. Pick the HTTP and axum features matching the project's major versions. For example: hotpath = { version = "0.28", features = ["tokio"] }.

Use this version, not the one the docs snippets show. If the project already depends on hotpath, keep its version.

If the crate already has a [features] section, merge the entries.

3. Instrument main

Docs: https://hotpath.rs/functions, https://hotpath.rs/profiling_modes.

  • Put #[hotpath::main] on main. With tokio, #[tokio::main] must come FIRST (above it). Defaults are fine for a first setup; don't add parameters unless asked.
  • If attribute placement on main is not possible, build a guard with HotpathGuardBuilder. The builder does not install the allocation-tracking allocator, so also declare hotpath::CountingAllocator as the #[global_allocator] ("Allocation tracking with HotpathGuardBuilder").
  • If the project already declares a custom global allocator (jemalloc, mimalloc, ...), follow "Custom inner allocator": the allocator = ... parameter with the macro, CountingAllocator::with(...) with the builder. Never leave two #[global_allocator] statics active under hotpath-alloc.

4. Instrument functions

Docs: https://hotpath.rs/functions.

  • Prefer #[hotpath::measure_all] on inline modules and impl blocks. Exclude noisy or trivial functions with #[hotpath::skip].
  • Use #[hotpath::measure] on individual functions, both sync and async, and hotpath::measure_block! for ad-hoc code blocks.
  • Start with hot paths: request handlers, worker loops, parsing/serialization, IO-heavy functions. Don't instrument one-line getters.
  • Don't try to instrument everything, use up to ~5 hotpath::measure_all annotations and up to 30 hotpath::measure. Goal of the initial setup is not to measure all functions, but to get the initial working instrumentation in place.

5. Wrap data-flow primitives

Docs: https://hotpath.rs/data_flow, https://hotpath.rs/locks, https://hotpath.rs/io_tracing.

Wrap channels, streams, futures, locks and I/O values at their creation site with the macro the docs give, with a label.

  • Call-site aggregation is the default for channel!, stream! and io!, and it is safe for unbounded instance churn. Use iter = true only where one row per instance is wanted and the number of instances is bounded.
  • For io!, wrap the side where the work happens ("Measured layers", "Compression encoders"), or the reported rate is meaningless.
  • Wrapper macros return types prefixed with hotpath::wrap; update type signatures where needed. Explain to the user that these types are no-op unless the hotpath feature is enabled. If that requires changes across many function boundaries, note it to the user rather than rewriting half the codebase silently.
  • Apply log = true only if Debug is already implemented.

6. Optional extras (only when relevant)

Fetch the page before adding one of these:

  • Tokio runtime metrics: https://hotpath.rs/tokio_runtime.
  • SQL profiling (sqlx, diesel, toasty): https://hotpath.rs/sql_tracing. Mind the "EnvFilter caveat".
  • HTTP client profiling (reqwest, ureq): https://hotpath.rs/http_tracing. Wrap the client once at creation; where it is stored in a struct or named in signatures, use the hotpath::wrap:: types. When both reqwest majors are enabled, 0.12 clients and errors use the versioned hotpath::wrap::reqwest_012 path. If the app already uses reqwest-middleware, attach the hotpath middleware to its stack instead of the macro.
  • axum server profiling: https://hotpath.rs/axum_tracing. Wrap the finished router, after the last route is added; with an existing tower stack, place the layer as "Existing middleware stacks" describes. Tell the user that route scoping of SQL queries and outbound HTTP requests is on by default and how to disable it. Async sqlx sqlite runs statements on its own worker thread, so it gets neither source nor route.

7. Add the policy file

mkdir -p hotpath
curl -fsSL https://hotpath.rs/api/v1/policy/default | jq -j .source > hotpath/policy.toml

Run it from the repository root. It writes the default regression policy, with comments, to hotpath/policy.toml (no token needed; with wget, use wget -qO- https://hotpath.rs/api/v1/policy/default). Never overwrite an existing policy file. Do not change the defaults unless the user asks; https://hotpath.rs/regression_policy documents every key.

8. Verify

cargo check                       # feature off: must still compile, zero overhead
cargo check --features hotpath    # feature on
cargo run --features hotpath      # prints report on exit

Optionally verify alloc mode: cargo run --features 'hotpath,hotpath-alloc'.

Report what was instrumented and mention next steps, with their docs links: the live TUI and report options (https://hotpath.rs/profiling_modes) and the environment variables (https://hotpath.rs/configuration). Report sections need no configuration, so mention HOTPATH_REPORT only if the user wants to restrict output.

Also explain to the user that hotpath is safe to keep as a regular (non-optional) dependency ("Optional vs non-optional" in https://hotpath.rs/profiling_modes).

Rules

  • Never enable the hotpath feature by default (default = []); profiling must stay opt-in.
  • Keep edits minimal: dependency, main, the policy file, and a sensible starting set of instrumented functions/primitives. Expand coverage only when the user asks.
  • When the docs and your memory of the API disagree, the docs win.

Similar Skills

receiving-code-review

OBobra/superpowers298k2,631 new stars in the last 7 days

requesting-code-review

OBobra/superpowers298k2,631 new stars in the last 7 days

systematic-debugging

OBobra/superpowers298k2,631 new stars in the last 7 days

code-review

MAmattpocock/skills288k10,178 new stars in the last 7 days

codebase-design

MAmattpocock/skills288k10,178 new stars in the last 7 days

scaffold-exercises

MAmattpocock/skills288k10,178 new stars in the last 7 days