Conversation
- repository: list_messages_after keyset query ((created_at, id) anchor); list_messages ORDER BY gains id tiebreak (same-timestamp rows could interleave); latest_message_by_role for single-row reads - engine/local_agent: per-iteration tail-only loads replace full-session rescans; compaction window loads only messages since last source_to - compaction: trigger sized from real provider payload instead of the drifting estimate; hysteresis (projected post-compaction size + messages-since-last-compaction gate) so a fresh compaction cannot immediately re-fire; forced /compact unchanged - tests: keyset/tiebreak/newest-of-role repository tests; trigger hysteresis unit tests
juacker
force-pushed
the
perf/compaction-bounded-loads-and-trigger
branch
from
September 21, 2026 18:33
bf695e2 to
7b40e53
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
Two compaction-related performance problems, confirmed by analysis of a real long session (12,064 messages / 64 MB):
engine.rs:222) — ~9 call sites did full scans. On the measured session that is 64 MB per iteration, ~6.4 GB of queries over 100 iterations.Changes (single commit, 5 files, +926/−117)
A. Bounded loads (repository.rs)
list_messages_after: keyset pagination anchored on(created_at, id)— loads only messages after a boundary row instead of the whole session.(created_at, id)ORDER BY tiebreak inlist_messages(fixes pre-existing ordering disagreement withlist_messages_before).latest_message_by_role: single-row reads for per-role lookups.local_agent(×3), andcompact_session_historyall converted to tail-only loads. Provider-visible history content/order is unchanged; divergence is confined to the intended tiebreak.Insertion-faithful ordering (review hardening)
next_created_atenforces a monotonic per-sessioncreated_aton insert (max(requested_now, session_max + 1ms)) inside the insert transaction, so the(created_at, id)total order equals insertion order for all new rows. Without this, a tool result sharing a millisecond with its owning assistant message could sort before it and be silently orphaned by a compaction boundary. Historical rows are untouched.B. Trigger rework (compaction.rs)
/compactpath unchanged.Tests
load_provider_historytests: boundary exclusion, standing summary leading, stale-summary filtering,messages_since_compaction, never-compacted full history, cross-session fallback).cargo fmt+cargo clippyclean.Review
Two independent review rounds; round-2 verdict production_quality. Known follow-up (accepted, non-gating): the
BEGIN → SELECT MAX → INSERTbump uses deferred-BEGIN WAL semantics, so a concurrent writer commit between read and write fails withSQLITE_BUSY_SNAPSHOT(same class already ships on main inupdate_pending_queued_message);BEGIN IMMEDIATEor a singleINSERT … SELECT MAX+1would remove it if it ever bites.Full analysis:
reviews/compaction-analysis/current-approach.mdin the workspace.