Skip to content

Releases: EricAndrechek/Pacer

Pacer 0.4.14

Choose a tag to compare

@github-actions github-actions released this 11 Aug 15:20
v0.4.14
f4b6151

More CPU work, this time aimed at keeping the Dashboard window open.

Optimised for the window being open

0.4.12 and 0.4.13 cut Pacer's CPU use a long way, but both were verified
with the Dashboard closed. If you keep the window open — on a second
monitor, say — that's the state that matters, and it had its own set of
problems.

Four pieces of work were repeating constantly for no benefit:

  • The burn-rate warning re-fitted a statistical model every time rate-limit
    data arrived, even though its inputs only change when the forecast is
    refit.
  • The toolbar's activity pill re-read the database on every write, to show
    a label that changes about once a minute.
  • The "Now" and "Today" tiles did the same, six times over.
  • The rate-limit charts reloaded eight days of history — about 25,700
    records — every time a poll added three new ones. They now load just
    the new ones.

No single part of Pacer now dominates its own CPU profile.

Also fixed

The "Now" tiles captured today's date and the current hour when the window
opened and kept them, so after an hour rolled over they read from the wrong
hour bucket until the window was reopened.


Requires macOS 15 or later. Update via Pacer's built-in updater, or download
below.

Pacer 0.4.13

Choose a tag to compare

@github-actions github-actions released this 11 Aug 13:40
v0.4.13
8a8cbb8

More CPU. This one is the big one.

Pacer was recomputing its whole forecast every 20 seconds

0.4.12 fixed the Dashboard window pegging a core. This fixes the rest,
which showed up as Pacer being busy in bursts even with no Claude Code
session running.

The forecasting engine — the thing behind projected fill, time-to-limit
and the pace bands — was refitting from scratch every time Pacer recorded
new usage, at most every 20 seconds. Each refit takes about 4.5 seconds of
real work. That is roughly a quarter of a CPU core, permanently, to
recompute answers that change over hours.

It now refits when the data it actually depends on changes — your
rate-limit windows — rather than every time a token is recorded.

Measured on a real machine with Claude Code actively running:

CPU
before ~100% of a core
after 0.4.12 ~16%
after this release ~7%

Forecasts are unchanged. They were already being recomputed far more often
than their answers could move.


Requires macOS 15 or later. Update via Pacer's built-in updater, or download
below.

Pacer 0.4.12

Choose a tag to compare

@github-actions github-actions released this 11 Aug 11:46
v0.4.12
16afb79

Fixes Pacer burning a CPU core while the Dashboard window is open.

The Dashboard was pegging a core

If you left the Dashboard window open, Pacer used roughly a full CPU core
continuously — measured at 103.9% with the window open versus 0.0% with it
closed. Fans up, battery down, for a background app whose entire job is to
sit quietly.

The rate-limit pace charts were reloading eight days of history — about
25,700 records — every single time anything was written to the database,
which happens constantly as Pacer records your usage. That work ran on the
main thread, which is also what draws the window.

They now reload only when new rate-limit data actually arrives, roughly
every five minutes. Same charts, same history, same live updates.

This affected 0.4.1 through 0.4.11. If you keep the Dashboard open, this is
worth updating for.

Also

DuckDB's background worker pool is now capped at one thread. It was sizing
itself to your CPU core count and keeping every one of those threads alive
for the life of the app, to do work that needs a single thread.


Requires macOS 15 or later. Update via Pacer's built-in updater, or download
below.

Pacer 0.4.11

Choose a tag to compare

@github-actions github-actions released this 10 Aug 12:45
v0.4.11
1b8dcb1

Fixes a menu-bar display bug at 100% usage.

"100%" no longer breaks the dropdown

When a window reached 100%, the menu-bar dropdown wrapped the number onto
two lines and pushed the label outside its ring. Three digits are one
character wider than every other reading, and both spots were sized for
two.

Reported by @jfwoods in #125 — thank you.

Readings below 100% are unchanged, pixel for pixel, including the gauges
in the dashboard and widgets.


Requires macOS 15 or later. Update via Pacer's built-in updater, or
download below.

Pacer 0.4.10

Choose a tag to compare

@github-actions github-actions released this 10 Aug 12:08
v0.4.10
f66c4f9

A fix for the raw archive, which was quietly recording some replies short.

Streamed replies were archived before they finished

Pacer's archive (added in 0.4.8) keeps a permanent record of every billable
turn. Claude Code writes a long reply to disk repeatedly as it streams, and
Pacer corrects its own records once the finished version arrives — but the
archive kept whichever version it saw first.

Over six days on a real machine that came to 466 turns holding roughly 2.35
million fewer output tokens than they should. Pacer's visible numbers were
never affected; only the archive was.

Pacer now checks the archive's contents against its own records rather than
just checking that a turn is present at all, and repairs anything that has
been superseded. Existing archives are corrected automatically on the next
launch — no action needed.

Nothing here changes the usage or cost figures you see.


Requires macOS 15 or later. Update via Pacer's built-in updater, or download
below.

Pacer 0.4.9

Choose a tag to compare

@github-actions github-actions released this 04 Aug 20:02
v0.4.9
d2a7e66

Faster rollups, and Pacer now checks its own archive.

Hourly figures rebuild ~47x faster

Recalculating an hour's usage was loading a whole day of that model's
records and filtering them in memory. It now asks for just that hour —
1,406 ms down to 30 ms on a large history. You'll notice it most if you
use Pacer heavily, where the background refresh could briefly stall.

The raw archive verifies itself

0.4.8 introduced an append-only archive of every billable turn. Pacer now
compares it against its main database every hour and records the result,
so a disagreement surfaces on its own instead of waiting for someone to
go looking.

It also fixes a case where turns that arrived out of order — which happens
whenever you resume an older session — could be left out of the archive
permanently.

Nothing here changes your numbers; 0.4.8 was the release that corrected
those.


Requires macOS 15 or later. Update via Pacer's built-in updater, or
download below.

Pacer 0.4.8

Choose a tag to compare

@github-actions github-actions released this 04 Aug 19:23
v0.4.8
a8b1962

Your costs were reading low. This release fixes that and rebuilds the history.

Costs were under-reported, and now self-correct

Pacer derives cost from tokens x pricing. If pricing hadn't finished loading
when a total was calculated — which routinely happened in the first seconds
after launch — everything computed in that window came out as $0. A $0 total
looks exactly like a real one, so nothing ever recalculated it, and the error
stayed permanently.

On a real store this showed up as one day's project totals sitting $663 below
the same day's daily total, all of it one model's spend.

Three fixes:

  • Pricing is now guaranteed to be loaded before any total is calculated.
  • When a brand-new model gets priced for the first time, Pacer now rebuilds
    its history automatically. Previously every model launch needed a Pacer
    update to correct the costs that had accumulated at $0.
  • Today's and the current hour's figures are recalculated from your raw usage
    every 10 minutes, so a number can't drift and then freeze when the hour
    rolls over.

Your existing totals are rebuilt once on first launch after updating. No
action needed, and nothing is deleted — Pacer keeps every raw sample and
recomputes from those.

Two days in May were counted twice

126 turns from May 6th and 7th had been recorded twice over, so both days
read higher than they should. Pacer now finds and collapses these on first
launch after updating.

Nothing is lost: the duplicate copies were identical to the ones kept, and
this is the only situation in which Pacer removes a raw record — it never
deletes your history by age or for space.

First launch is 3.3x faster

Setting Pacer up used to mean waiting while it read every transcript you had
ever written, one line at a time. On a 1,700-file, 1.9 GB history that was
47 seconds of an unresponsive app.

It now reads them all at once: 14.3 seconds, with results verified
identical to the old path down to the individual token.

This only affects first launch and full re-scans. Ongoing updates are
unchanged — Pacer still watches for file changes and reads only the bytes
that changed, at ~0% idle CPU.

Under the hood

Pacer now keeps an append-only archive of every billable turn it has seen,
alongside the main database. Nothing user-visible reads it yet; it's the
foundation for keeping full history without the storage growing unbounded.
It never deletes anything.


Requires macOS 15 or later. Update via Pacer's built-in updater, or download
below.

Pacer 0.4.7

Choose a tag to compare

@github-actions github-actions released this 04 Aug 15:11
v0.4.7
6e308c1

Launches in a fraction of a second

Pacer used to rebuild its duplicate-detection map on startup by reading every usage row it had ever stored — 9 to 16 seconds on a large history, and getting slower as that history grew. It now keeps that map on disk beside the store and loads it in milliseconds.

On a 190,000-row history, startup went from 9.3 seconds to 42 milliseconds.

The map is treated as a cache, never as the truth: if it doesn't account for exactly the rows in the store it's thrown away and rebuilt, because a duplicate-detection map that quietly disagrees with your data is worse than none at all.

Also in this release:

  • Idle scan cycles no longer do a database query just to decide they have nothing to do
  • Rollup totals and cost are now checkable against the raw data with make verify-data

Pacer 0.4.6

Choose a tag to compare

@github-actions github-actions released this 04 Aug 14:21
v0.4.6
97af535

Fixes hourly bucketing on the incremental path

Completes the v0.4.5 fix. Pacer has two code paths that decide which hour an entry belongs to — one for full rebuilds, one for the ordinary incremental scan that runs continuously. v0.4.5 only fixed the first, so the drift would have quietly returned at the next daylight-saving change through the path that runs every day.

Both now read the stored hour. If you already updated to v0.4.5, your history was rebuilt correctly and stays correct.

Pacer 0.4.5

Choose a tag to compare

@github-actions github-actions released this 04 Aug 14:12
v0.4.5
4e60ab9

Fixes hourly usage filed under the wrong hour

Follow-up to v0.4.4, and the deeper half of the same problem.

Removing leftover rows only helped when the entry's new hour had no row yet. When both hours already had rows, the numbers were simply filed under the wrong one and nothing corrected them — on the maintainer's history, 64 of 1,440 hourly buckets held another hour's totals, one reading 289,000 output tokens too low while its neighbour ran 253,000 too high.

The cause: Pacer stored the date an entry belonged to but recalculated the hour every time it read one, using whatever timezone was current. A daylight-saving or timezone change silently refiled all your history. Daily totals were never affected because the date was stored rather than recalculated.

The hour is now stored alongside the date, so it can't move. Your existing history is rebuilt automatically on first launch after updating — it takes under a minute and never deletes anything.

If you want to check your own store: make verify-data.