perf(hub): cache sessionAgentIDs on archived sessions (#118 §1)#295
Merged
Conversation
sessionAgentIDs ran `GROUP BY agent_id ORDER BY MIN(ts)` over a session's full agent_events span on *every* digest/turns read — even when the digest was already fresh. For a 10k-event session that is a 10k-row index scan per Insight open (#118 bottleneck #2). Denormalize the result onto a new `sessions.agent_ids_json` column, materialized lazily and ONLY for terminal (archived) sessions whose agent set can no longer grow. A paused session can resume and bind a new agent, so non-archived sessions keep scanning authoritatively — behaviour is byte-identical for live/paused sessions and a malformed/empty blob falls through to the scan. Read-repair writes the set back on the first archived read. - migration 0060: `sessions.agent_ids_json TEXT` (nullable) - sessionAgentIDs: archived + cached -> O(1) parse; else scan (+ write-back) - test: scan-not-cached while active; materialize + served-from-cache once archived (a later out-of-band event is NOT re-scanned) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This was referenced Jun 27, 2026
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.
First of three Tier-A perf PRs for #118 (Insight transcript ~10s load on 10k-event sessions). Verified the issue's analysis against the tree — all bottlenecks intact — and split the safe wins into separate PRs.
Problem (#118 bottleneck #2)
sessionAgentIDsrunsGROUP BY agent_id ORDER BY MIN(ts)over a session's fullagent_eventsspan on every digest/turns read — even when the digest is already fresh. For a 10k-event session that's a 10k-row index scan per Insight open, and it's called from the digest handler, the turns handler, and OTLP export.Fix
Denormalize the result onto a new
sessions.agent_ids_jsoncolumn, materialized lazily and only for terminal (archived) sessions whose agent set can no longer grow.pausedsession can resume and bind a new agent (handlers_sessions.go:705), so non-archived sessions keep scanning authoritatively → byte-identical behaviour for live/paused sessions.archivedis terminal (no transition back), so its agent set is immutable and safe to cache.Changes
0060_sessions_agent_ids:sessions.agent_ids_json TEXT(nullable)sessionAgentIDs: archived + cached → O(1) JSON parse; else scan (+ write-back when archived)TestSessionAgentIDs_CachesOnlyWhenArchived: not cached while active; materialized + served-from-cache once archived (a later out-of-band event is not re-scanned, proving the O(1) path)Verification
go build,go vet, gofmt clean; digest/turns/insights/OTLP/migration suites pass locally.Part of #118 (Tier A). Follow-ups: digest read-cache (§2-cache), fold-on-session-close.
🤖 Generated with Claude Code