Revolution1/thermtrace

Local macOS process and thermal monitor with SQLite capture and agent-ready analysis.

★ 0Forks 0PythonGitHub ↗Compare

README

thermtrace

thermtrace is a local macOS monitor for one specific workflow:

  1. capture process, load, thermal, and sensor data into SQLite
  2. inspect the hot windows quickly from the CLI or TUI
  3. hand the database to Codex or another agent for deeper analysis

It is optimized for "my Mac got hot / slow, what actually caused it?" rather than for generic uptime monitoring.

What It Looks Like

Live collection UI

Live collection UI

CLI analysis output

CLI analysis output

Agent handoff prompt

Agent handoff prompt

Install

System requirements:

  • macOS
  • Python 3.9+
  • uv recommended

Install the Python dependencies:

uv sync

Install optional sensor tools if you want richer temperature data:

brew install ismc

Notes:

  • thermtrace works without these tools, but temperature coverage will be more limited.
  • The bundled Apple Silicon helper is compiled automatically with clang on first use when available.
  • powermetrics is built into macOS, but full thermal sampling may require sudo.
  • ismc is the simplest optional dependency to add if you want actual temperature readings without relying on the Apple Silicon helper alone.

Run from source:

uv run thermtrace --help

The default database path is:

~/Library/Application Support/thermtrace/thermtrace.sqlite3

You can override it with --db /path/to/thermtrace.sqlite3.

Tutorial

1. Start collecting

Interactive mode is the default when you are in a terminal:

uv run thermtrace collect -i 2 --note "external monitor + VS Code + Chrome"

Live collection UI

Useful flags:

  • -i, --interval: sample interval in seconds
  • -d, --duration: stop automatically after N seconds
  • --process-limit: number of per-sample processes to keep
  • --non-interactive: collect without launching the TUI

Example for a fixed 10-minute capture:

uv run thermtrace collect -i 2 -d 600 --note "battery drain repro"

2. Find the interesting run

uv run thermtrace runs
uv run thermtrace db-summary

If you recorded several sessions, inspect a specific one:

uv run thermtrace db-summary --run-id 7

3. Identify hot processes and time windows

Start with the built-in summaries:

uv run thermtrace top --run-id 7
uv run thermtrace hot-samples --run-id 7
uv run thermtrace analyze --run-id 7

CLI analysis output

Useful drill-down commands:

uv run thermtrace sample 31
uv run thermtrace timeline --run-id 7
uv run thermtrace sensors --run-id 7 --metric temperature
uv run thermtrace vscode --run-id 7

Recommended reading order:

  1. db-summary for overall shape
  2. analyze for likely culprits
  3. hot-samples and sample for evidence
  4. sensors if the run involved heat or throttling

4. Hand the run to an agent

Generate a prompt with schema, goals, and starter SQL:

uv run thermtrace agent-prompt --run-id 7

Agent handoff prompt

Then paste that prompt into Codex, together with a short task such as:

Use the SQLite database at the path above. Focus on run 7. Tell me which processes most likely caused the heat spike, cite sample ids and timestamps, and separate steady background load from short spikes.

If you want the agent to inspect the DB directly with sqlite3, tell it explicitly. The generated prompt already includes the database path, run id, schema, and suggested SQL starting points.

Sensor Notes

thermtrace always records process and load data. Temperature data is best-effort and depends on what is available on the machine.

Potential sources include:

  • ismc
  • powermetrics
  • the bundled Apple Silicon HID helper

To inspect what your machine can provide:

uv run thermtrace diagnose-sensors

Example Analysis

Below is a sanitized example based on a real local capture from this project database. It is written in the style you would expect from an agent after inspecting the SQLite data.

Scenario:

  • run id: 9
  • duration: about 2 hours 45 minutes
  • samples: 3026
  • process rows: 121040
  • temperature rows: 217872
  • sensor source used in this run: ismc

High-level result:

  • The hottest sustained load came from an editor stack, not from a short-lived system daemon spike.
  • Two renderer/helper processes from the editor were the main source of pressure across the hottest windows.
  • A Python process was a steady secondary contributor.
  • Browser renderer activity was present, but clearly below the editor renderers during the worst heat intervals.
  • No OS thermal warning was recorded, but the run still reached 96.4C, which is enough to justify investigation.

Supporting evidence:

  • Run average busy CPU was 40.8%, with a run peak of 63.7%.
  • Peak recorded temperature was 96.4C.
  • The built-in analysis flagged 37 hot samples with no thermal warning samples.
  • The hottest temperature samples clustered around 2026-04-01T06:47:58+00:00, 2026-04-01T06:59:59+00:00, and 2026-04-01T07:18:31+00:00.

Sanitized process ranking:

  1. Editor renderer A: sustained triple-digit CPU in hot windows, peak about 255%
  2. Editor renderer B: sustained triple-digit CPU in hot windows, peak about 146%
  3. Python worker: recurring secondary load, peak about 97%
  4. Browser renderer: present in the same windows, but much lower, peak about 38%
  5. Editor plugin/helper: recurring background contributor, peak about 101%

Example conclusion:

This run looks like a sustained high-heat editor workload rather than a random macOS thermal event. The strongest evidence is that two editor renderer/helper processes recur across the flagged hot windows and dominate both average and peak CPU. Python contributes meaningfully but remains secondary. Browser renderers are present, but they do not explain the top thermal moments on their own.

What I would do next:

  1. Reproduce with the editor open but heavy tabs, extensions, and integrated terminals disabled one group at a time.
  2. Compare a control run with the browser still open, to confirm the browser is not the primary driver.
  3. If needed, use thermtrace vscode --run-id 9 or direct SQL to split editor load into renderer, plugin host, GPU, and terminal child processes.

Repo Structure

Regenerating README Assets

The screenshots in this README are generated, not hand-captured:

./.venv/bin/python scripts/generate_readme_assets.py

That script rebuilds the SVG assets in docs/assets/.

Contributors

Revolution1

Issues