Operations · 03 macOS only

Upgrade

Upgrade the Halton Meter daemon in place — uvx, uv tool, or pipx; plist regeneration; what survives the bump. The edge keeps your tools running through the swap.

macOS 12+ · Python 3.11+ Reading time 2 min Updated May 11, 2026

Halton Meter ships as a single PyPI package, halton-meter. Upgrading is a package swap plus a plist regeneration. The edge process stays bound to port 8081 through the whole sequence, so apps with HTTPS_PROXY baked into their environ keep working in pure-passthrough mode while the daemon swaps under them — see Fail-open behaviour.

The upgrade sequence

Pick the channel you installed with:

~ — uvx (canonical, ephemeral)
$ halton-meter --version                  # before
$ uv cache clean halton-meter          # force a fresh fetch
$ uvx halton-meter --version           # picks up the latest wheel
$ halton-meter init                       # regenerate plists pointing at the new binary path
$ halton-meter status                     # confirm new version is live
~ — uv tool (persistent on PATH)
$ halton-meter --version                  # before
$ uv tool upgrade halton-meter         # in-place upgrade
$ halton-meter init                       # regenerate plists
$ halton-meter status                     # confirm
~ — pipx
$ halton-meter --version                  # before
$ pipx upgrade halton-meter             # in-place upgrade
$ halton-meter init                       # regenerate plists
$ halton-meter status                     # confirm

The second init is required because the launchd plists embed the absolute path to the halton-meter binary in their ProgramArguments. A package upgrade may or may not change that path; re-running init regenerates the plists and bootstraps the new processes.

init is idempotent — running it twice does no harm. The cert is detected as already trusted, the certifi marker is detected, the existing plists are diffed against the regenerated ones, and the daemon is restarted only if something actually changed.

What survives an upgrade

SurfaceSurvives?
~/.halton-meter/db.sqliteYes — your captured data
~/.halton-meter/config.tomlYes
~/.mitmproxy/mitmproxy-ca-cert.pemYes — same CA
Keychain trustYes
certifi patchRe-validated by init; re-applied if the bundle changed
Shell rc blockRe-written if the env-var set changed
launchctl user-domain envRe-applied
launchd plistsRegenerated and bootstrapped

Your captured cost data is never touched on upgrade. To migrate the SQLite schema, the daemon runs _migrations rows on first connect; if a release ships a schema change, it migrates in place on next start.

Channel summary

ChannelFirst installUpgrade
uvx (canonical, ephemeral)uvx halton-meter init --appsuv cache clean halton-meter && uvx halton-meter --version
uv tool (persistent on PATH)uv tool install halton-meteruv tool upgrade halton-meter
pipxpipx install halton-meterpipx upgrade halton-meter
pip (in a venv)pip install halton-meterpip install --upgrade halton-meter

After any of the above, run halton-meter init to regenerate plists.

What if the new daemon won’t start

Roll back to the previous version and file an issue with halton-meter doctor --json output:

~ — pin a previous version
$ uv tool install --force halton-meter==0.2.10
# or, with pipx:
$ pipx install --force halton-meter==0.2.10
$ halton-meter init
$ halton-meter status

If the daemon hangs in the start self-test for the full 30 seconds, Init self-test fails immediately covers the common causes (port held by an old daemon, certifi marker missing on a venv that just bumped Python).

What’s next

  • Troubleshooting — the diagnostic tree when an upgrade leaves something broken
  • Logs — where the post-upgrade structured events land