Skip to main content

tachometer

Shared repo and resource profiling helpers for the portfolio.

tachometer extracts the reusable profiling contract that first lived in the portfolio's original per-repo profiler: resource snapshots, persisted sample history, command profiling, and portable JSON summaries. Downstream repos keep their own workload logic. tachometer owns the common profiling model, CLI, and repo-local manifest convention.

Scope

tachometer currently provides:

  • host resource snapshots: CPU, load average, memory, disk, and optional GPU
  • canonical host profile and summary artifacts for the dashboard banner
  • local AI-provider utilization snapshots for Claude, Codex, and Copilot when their local CLI caches expose usage
  • optional Fedora-specific sidecar signals exported by fedora-debugg
  • repo snapshots: repo size, file and directory counts, and git tracked/dirty or untracked counts when git is available
  • profiled command runs with pre and post samples plus runtime metadata
  • manifest-driven profile and summary paths so every repo can use the same local output convention

tachometer does not yet try to own:

  • repo-specific stoplight policies or adaptive controller logic
  • portfolio-wide dashboards or central metric shipping
  • long-running daemon collection

That split is intentional. The origin profiler keeps its controller and system monitor; tachometer owns the lower-level profiling primitive those features depend on.

Platform support

The package installs and the CLI runs on Linux, macOS and Windows, verified by CI on every push. How much it can actually measure differs sharply, because most signals come from interfaces only Linux provides.

Signal source Linux macOS Windows
Repo metrics (size, file counts, git) yes yes yes
Disk usage yes yes yes
Child CPU time, peak RSS, page faults (resource) yes yes no
Per-process CPU, memory, I/O (psutil, optional) yes yes yes
Load average, memory detail, uptime, process count (/proc) yes no no
CPU temperature, fan RPM (/sys/class) yes no no
Energy in joules (Intel RAPL) yes no no
GPU (nvidia-smi) if present if present if present

What this means in practice

Linux is the reference platform. Everything above works.

macOS loses the /proc and /sys signals — no load average detail, memory breakdown, uptime, process count, temperature, fan or energy. Child-process CPU and memory still work, because resource is a Unix module.

Windows additionally loses resource, which does not exist there at all. Without psutil installed, a profiled command reports None for CPU percent, peak RSS and fault counts.

psutil is not a declared dependency, so on Windows it is worth installing explicitly for anything beyond timing:

pip install psutil

Fields that cannot be measured are reported as None rather than 0, so a missing signal is distinguishable from a genuine zero. Widening native Windows coverage is tracked in BACKLOG.md.

Install

python3 -m venv .venv
. .venv/bin/activate
pip install -e .[dev]

CLI

Capture a repo snapshot from a tracked manifest:

tachometer snapshot --manifest examples/example-repo/repo-profile.toml

Capture the canonical host snapshot used by the portfolio dashboard banner:

tachometer host-snapshot --manifest config/tachometer/profile.toml

Profile a command and append pre/post samples plus a run record:

tachometer run --manifest examples/example-repo/repo-profile.toml -- python3 -m pytest -q

Print the current JSON summary:

tachometer summarize --manifest examples/example-repo/repo-profile.toml

Print the current canonical host summary:

tachometer host-summarize --manifest config/tachometer/profile.toml

Capture the local AI-provider utilization snapshot used by the dashboard:

tachometer agent-utilization --manifest config/tachometer/profile.toml

Record one host temperature and load sample for the thermal history (meant to run every five minutes; see config/clockwork/host-sampler.toml.template):

bash scripts/sample_host.sh

The dashboard charts the history at /thermal.

To add SMART drive temperatures and a Drive health light, set TACHOMETER_SMART_DIR for the sampler to a directory that a separate root-run collector fills with one <drive>.jsonl per drive. Each line is one snapshot with taken_at (ISO 8601), kind, health_passed, temperature_c and counters; the sampler reads the last two lines and ignores snapshots older than three hours. Unset or empty, the sampler reads no SMART data. Set it in the rendered, gitignored manifest config/clockwork/host-sampler.toml so the path stays out of the tracked template:

[jobs.environment]
TACHOMETER_SMART_DIR = "/path/to/smart/history"

The rendered manifest is per machine. On macOS, install it with --target launchd-user (clockwork 2026-10-15 or newer renders the five-minute calendar there) and leave TACHOMETER_SMART_DIR empty. The sampler then reads what macOS exposes without root: each physical disk's SMART verdict from diskutil, which drives the Drive health light, and the battery temperature from ioreg where the battery reports one, charted as the board reading. Recent Apple Silicon laptops publish no battery temperature to ioreg at all (checked on a MacBook Air, 2026-10-15), so there the board reading stays empty. diskutil reports no temperatures or counters, and CPU temperature on macOS needs root, so those stay empty too. The launchd job puts Homebrew's bin first on PATH because tachometer needs Python 3.10 or newer.

For what macOS reserves for root, install the root-run collector once:

sudo bash scripts/macos/install_powermetrics_collector.sh

It installs a root-owned copy of scripts/macos/powermetrics_collector.py under /usr/local/libexec/tachometer (the daemon never runs the editable checkout) and a LaunchDaemon that appends one powermetrics reading every five minutes to /var/db/tachometer/powermetrics.jsonl. Set TACHOMETER_MACOS_POWERMETRICS to that file in the rendered manifest's [jobs.launchd.environment] and reinstall the sampler. Every Mac then gets a Thermal pressure light (Nominal, Fair, Serious, Critical); Intel Macs also get CPU and GPU die temperature and fan speed. Apple Silicon powermetrics reports no temperatures, only pressure and power. --uninstall removes the daemon.

Serve the dashboard on loopback only:

tachometer serve --manifest config/tachometer/profile.toml --host 127.0.0.1 --port 5100

Non-loopback binds are blocked unless you pass --allow-remote explicitly. Dashboard-triggered Run All Snapshots writes the active run to .tachometer/run-all.log; before a new run starts, the previous non-empty log is archived under .tachometer/logs/run-all-<timestamp>.log. The 10 newest archives stay loose for quick inspection; older archives are compressed into date-based bundles under .tachometer/logs/bundles/run-all-YYYYMMDD.zip.

If fedora-debugg has exported artifacts/latest/tachometer-signals.json, the dashboard also renders a separate Fedora Debug strip with snapshot age plus bucketed Collection, Display, Coredumps, GPU, Storage, Packages, Python, Node, and Go signals.

If .tachometer/agent-utilization.json exists, the dashboard also renders an AI Utilization strip sourced from local CLI state:

  • Claude: ~/.claude/stats-cache.json plus claude auth status --json
  • Codex: the latest .codex session token_count event with rate-limit data
  • Copilot: the latest .copilot/session-state/*/events.jsonl shutdown record

Copilot usage only appears after at least one session has started, and the current session totals land when that session shuts down.

Disk Pressure Response

When disk utilization crosses the red threshold, tachometer writes an open system.disk or host.disk item to the local .tachometer/backlog.json / .tachometer/host-backlog.json file. The shared remediation path lives in ./util-repos/traction-control: its tachometer disk-pressure agentic job scans those backlog and summary files, selects clean pressure candidates, and launches an agent to add reversible repo-local archive automation.

The standard fix pattern is intentionally conservative: compress/decompress local-only caches, generated artefacts, temporary downloads, and debug snapshots with an audit trail; never delete source data or raw private inputs as the default pressure response.

Manifest Shape

[repo]
name = "example-repo"
category = "health-repos"
kind = "python"

[paths]
disk_path = "."
profile_path = ".tachometer/profile.json"
summary_path = ".tachometer/summary.json"
host_profile_path = ".tachometer/host-profile.json"
host_summary_path = ".tachometer/host-summary.json"

[defaults]
label = "repo-snapshot"

Manifest rules:

  • manifests live at config/tachometer/profile.toml in downstream repos
  • the repo root is inferred from the manifest location
  • .tachometer/ is the standard local-only output directory
  • disk_path is resolved relative to the repo root
  • host_profile_path and host_summary_path default to canonical dashboard artifacts and are primarily used by the tachometer repo itself

Portfolio Rollout

The shared utility repo is paired with a lightweight downstream convention:

  • config/tachometer/profile.toml
  • scripts/run_tachometer_profile.sh
  • .gitignore entry for .tachometer/

That gives every repo one stable local profiling entrypoint while keeping the actual profiler implementation centralized here.

Development

ruff check .
ruff format --check .
black --check --diff .
pytest -q

Contributing

See CONTRIBUTING.md.

License

MIT. See LICENSE.

Metadata

Release files for tachometer 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for tachometer 0.1.0
File Size Uploaded
tachometer-0.1.0.tar.gz 77.9 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for tachometer 0.1.0
File Interpreter ABI Platform
tachometer-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 141.6 kB

Release files / tachometer-0.1.0.tar.gz

Download URL tachometer-0.1.0.tar.gz
Size 77.9 kB
Tags Source
SHA-256 checksum
How to use checksums
a51803501d9f62f38ce9cb9673907c30d7550e73ea7a9dd800309f9676ce4c73
BLAKE2b-256 checksum
How to use checksums
734ade2de2f81ec71e8369ab7362d89b20eb89b7e851e873b09661ac828d965b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 18, 2026.

Transparency log

Release files / tachometer-0.1.0-py3-none-any.whl

Download URL tachometer-0.1.0-py3-none-any.whl
Size 63.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
7139a116ea0e10051ec4b2bac7994c95830634e1fc82fb8b184fd8c20e06f55b
BLAKE2b-256 checksum
How to use checksums
cad4961245a68ed66db6ba768c61405352c1b14aea3f0598089cb4b4aa3b6e55
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 18, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page