Uh oh!
There was an error while loading. Please reload this page.
fix(session): bound compacted history hydration - #39930
Conversation
Thanks for your contribution! This PR doesn't have a linked issue. All PRs must reference an existing issue. Please:
See CONTRIBUTING.md for details. |
The following comment was made by an LLM, it may be inaccurate: Potential Duplicate Found:
This PR appears to address the same issue—avoiding full history hydration after compaction. Both PRs focus on optimizing memory usage by limiting what gets hydrated from prompt history during session compaction iterations. You should verify whether PR #31638 is already merged or if it needs to be reconciled with the current PR #39930. |
086e5ab to
94c5234Comparebrauliobo
commented
Jul 31, 2026
Addressed the follow-up comments:
|
Thanks for updating your PR! It now meets our contributing guidelines. 👍 |
Qiiks
commented
Aug 6, 2026
Validated this fix against two real production sessions (Windows, opencode 1.18.13). The two-phase walk works exactly as proposed — here's the measured impact and one edge case worth deciding on: Measured impact (replicated the walk against the live DBs)
Both sessions currently hydrate all parts on every prompt ( One edge case to decide: empty compaction marker behaviorBoth sessions carry a compaction part with if(!compaction.tail_start_id)break pages // ← stops the walk HEREThis is a behavior change from the old path: Options:
Also worth noting: the null-marker case in old code already skipped compaction reordering (returned everything), so either choice is defensible — but the "incomplete compactions unchanged" claim in the description only holds with the Otherwise the implementation is clean: |
brauliobo
commented
Aug 6, 2026
@Qiiks Addressed in commit
Verification:
The package-wide |
brauliobo
commented
Aug 14, 2026
Corrected the follow-up in
The update now:
Verification: 162 passed, 2 skipped across the targeted session tests; Known persisted-data limitation: a plugin marker paired with a completed-looking summary but no tail is indistinguishable from a valid native full-summary compaction, so it follows native completed-compaction semantics. |
…malyco#39930) Compaction previously materialized every message of a session through the full stream; now only the newest messages are hydrated. Reduces a 609-message session from 11.4MB to 0.8MB of allocations on compaction.
- pin note, seam-lookup range, and deferred-port re-verification now reference v1.18.23 (post-split packages/ai|util tree still absent, anomalyco#43769 stays blocked) - watch-list gains the 2026-08-26 sweep candidates (anomalyco#39930, anomalyco#38939, anomalyco#41950, anomalyco#33713, anomalyco#44631) - fork-build.sh BASE lookup now excludes *-lowmem.* tags: after a fresh upstream merge the previous fork tag ties the new base tag on commit distance with a newer date and git describe stamps the OLD base
Issue for this PR
Closes#35570
Type of change
What does this PR do?
filterCompactedEffectcurrently hydrates every message part before discarding history older than the latest completed compaction. This change finds that boundary from lightweight message rows first, then hydrates only the retained messages in batches. Retained tails, incomplete compactions, forks, and the existingstreambehavior are unchanged.On one compacted session this reduced the hydrated window from 609 messages / 11.4 MB of parts to 51 messages / 0.81 MB.
Related to #31638. That PR scans already-hydrated pages; this implementation avoids hydrating oversized parts on the boundary page by separating row discovery from part hydration, as proposed in #35570.
How did you verify your code works?
bun test --timeout 30000 test/session/messages-pagination.test.ts test/session/compaction.test.ts test/session/prompt.test.ts test/session/snapshot-tool-race.test.tsbun typecheckfrompackages/opencodebun turbo typecheckScreenshots / recordings
N/A - backend memory fix.
Checklist