Skip to content

perf: bound the daemon's warm mirror to recent history (#167) - #172

Merged
yonidavidson merged 1 commit into
mainfrom
perf/167-bounded-mirror
Aug 9, 2026
Merged

yonidavidson merged 1 commit into
mainfrom
perf/167-bounded-mirror

Conversation

@yonidavidson

Copy link
Copy Markdown
Owner

Closes #167. (Supersedes #168, auto-closed by GitHub when its base branch merged; same commit, rebased onto main.)

The daemon mirrored the entire bus — every key and every body — and refreshed it on every poll. That read every blob in the store each time: pending mail, the roster, the whole 30-day archive, and every telemetry batch. The cost of a poll grew with all history, forever, on a bus where nothing but the last few messages is hot.

What changed

  • src/daemon.ts — a warm-window policy: agents/ re-read every poll (records mutate), inbox/ always warm, read/ and events/ warm only inside AGENTCOMM_MIRROR_HISTORY_MS (default 7 days). Aged-out history keeps its key, so list, log, purge and channel discovery see the whole store exactly as before; the body loads on demand through the existing get passthrough. Immutable blobs already held are never re-read, so steady state is "the roster plus whatever is new".
  • src/types.ts / src/backends/git.tsSnapshottable.snapshot(prefix, {bodies}) now takes a body filter and returns {keys, bodies}. Listing names (ls-tree) is cheap; cat-file over every object is not.

Tests

  • test/git.e2e.test.ts: a snapshot reads only the requested bodies while still reporting every key, and a skipped body is still one get away.
  • test/daemon.e2e.test.ts: a month-old archived message is outside the window, yet log still returns its body and purge --dry-run still counts it.

The daemon mirrored the entire bus — every key AND every body — and
refreshed it on every poll. On a snapshot-capable backend that is one round
trip, but it read every blob in the store each time: pending mail, the
roster, the whole 30-day archive, and every telemetry batch. The cost of a
poll therefore grew with all history, forever, on a bus where nothing but
the last few messages is hot.

The mirror now holds what is worth holding. `agents/` is re-read every poll
(records mutate); `inbox/` is always warm; `read/` and `events/` are warm
only inside a window (AGENTCOMM_MIRROR_HISTORY_MS, default 7 days). Older
history keeps its KEY, so list, log, purge and channel discovery see the
whole store exactly as before, and a cold body loads on demand through the
`get` passthrough. Message blobs are immutable, so a body already held is
never re-read either: steady state is "the roster plus whatever is new".

`Snapshottable.snapshot` grew a body filter and now reports the keys it saw
alongside the bodies it read — listing names is cheap, reading blobs is not.
@yonidavidson
yonidavidson merged commit b93fd4a into main Aug 9, 2026
2 checks passed
@yonidavidson
yonidavidson deleted the perf/167-bounded-mirror branch August 9, 2026 08:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

The daemon re-reads the whole bus history on every poll — bound the warm mirror to a recent window

1 participant