Skip to content

Conversation cache: --conversation-cache-park-gain N (opt-in, default 0): a turn that grew a few hundred tokens no longer rewrites a whole 3 GB snapshot - #2265

Closed
Krypto-Whitehat wants to merge 1 commit into
Niko1221:mainfrom
Krypto-Whitehat:conversation-cache-park-gain
Closed

Krypto-Whitehat wants to merge 1 commit into
Niko1221:mainfrom
Krypto-Whitehat:conversation-cache-park-gain

Conversation

@Krypto-Whitehat

@Krypto-Whitehat Krypto-Whitehat commented Oct 13, 2026 •

Copy link
Copy Markdown
Contributor

Issue: Resolves #2264

Summary

--conversation-cache-park-gain N makes parking rate-limited by growth, opt-in and default 0 = park every turn, byte-identical to today. A conversation that advanced fewer than N tokens since the copy it would supersede keeps that copy: it still holds this conversation's prefix (a conversation only appends), and re-parking writes the whole snapshot only for the next turn to drop it again.

The report behind this measured 1,418 successful parks for one long single conversation, 2,251.9 GB of host copy written and 105.8 GB (4.7 %) ever read back, with 425 superseded copies dropped and 1,548 s of copy time on the request path. With the gate on it measured 3 park events and 3.26 GB (-66.7 %), the remaining copy being the conversation's first park.

The default stays off because the measurement is from one rig. Deciding whether it should be on by default is the maintainer's call, and nothing here forecloses it.

What changed

  • include/strata/core/conversation_cache.hpp: one new const accessor, parked_prefix_tokens(ids, images, checkpoints, cvec). It reports, in tokens, the longest parked entry the outgoing state supersedes - exactly the entries drop_superseded() would remove, found the same way drop_superseded() finds them (deepest checkpoint the outgoing chain still holds), so the gate can never name a different entry than the one a park would drop.
  • src/program/generate.cpp, the park decision (line 10445 at a0116b27): the existing condition gains one term, park_worth. With the default 0 that term is constantly true and the line behaves as before.
  • src/program/generate.cpp: the option, the --conversation-cache-park-gain N parse (alongside the other --conversation-cache-* flags, same INT32_MAX bound as --conversation-cache-slots), and the help text.
  • src/core/conversation_cache_test.cpp: seven checks for the accessor - an empty cache, parking a conversation, the entry the chain supersedes, another conversation sharing only the root, the other steering mode, an appended tail, and an entry without checkpoints.

Left alone on purpose: the default (0, so no behaviour change without the flag), the copy path itself, drop_superseded() and the K/V retention, the physical-RAM admission gate, and every log line. This is one flag, one accessor and one term in one condition.

Extra Notes

  • Checked by build: cmake -DSTRATA_ENABLE_CUDA=ON -DCMAKE_CUDA_ARCHITECTURES=89 with nvcc 13.4.92 and MSVC 14.44. The strata target compiles and links with 0 errors (Windows CUDA, sm_89, so the Linux-only paths of this file are not what that compiles). conversation_cache_test builds and passes: 4,226 checks, exit 0.
  • The unit test earned its keep: it failed the first assertion because I had expected the entry's live length (6) where the accessor reports the deepest checkpoint (5). drop_superseded() keys on the checkpoint, so 5 is the right answer and the expectation was wrong.
  • Not tested here: HIP and SYCL (no toolchain on this machine), and no decode run on this box - there is no model and no matching rig. Every tok/s number in the issue comes from the reporter's own A/B on an RTX 5090 Laptop, not from a run of this patch. What is verified here is that the change compiles and that the accessor names exactly what a park would supersede.
  • The gate is a policy decision with a real trade-off the maintainer should weigh: a conversation that rewrites (edits an earlier turn) is not a prefix of its parked copy, so with the gate on, such a conversation keeps an entry it cannot reuse until it grows past the threshold. That is the same loss the cache already accepts for drop_superseded, and it is why this ships opt-in.

…t grew a few hundred tokens from rewriting a whole snapshot (RTX 5090 Laptop, IQ3_XXS: 1,418 parks -> 1, 2,251.9 GB -> 3.26 GB host copy at 4.7 % read back; decode -3.4 %, inside the run-to-run spread)

A conversation that only advanced a few hundred tokens since its last park does not need a fresh 3 GB copy: the entry it would supersede still holds this conversation's prefix, and the next turn drops the copy anyway (drop_superseded). Reported in Niko1221#2264 over 1,418 park events on one long single conversation.

The flag is opt-in and defaults to 0, which parks every turn exactly as before. What this adds is a way to ask for the gate without a rebuild: on the reporter's rig it is 3.26 GB instead of 9.79 GB per benchmark, the superseded class disappears, and the decode median moves -3.4 %, inside that arm's 92.2-124.1 tok/s spread.

parked_prefix_tokens() reports exactly the entries drop_superseded() would remove - it finds them the same way, by the deepest checkpoint the outgoing chain still holds - so the gate cannot name a different entry than the park would drop. conversation_cache_test covers it (7 checks; 4,226 pass).

Fixes Niko1221#2264
DamirLukina88 pushed a commit to DamirLukina88/D.L.-AI---Strata that referenced this pull request Oct 13, 2026
…ache-park-gain N (opt-in, default 0): a turn that grew a few hundred tokens no longer rewrites a whole 3 GB snapshot

Source: Niko1221#2265

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
DamirLukina88 pushed a commit to DamirLukina88/D.L.-AI---Strata that referenced this pull request Oct 13, 2026
…up robustness, conversation cache memory)

Serve: Niko1221#2290 Niko1221#2284 Niko1221#2285 Niko1221#2170 Niko1221#2140 Niko1221#2278. Setup: Niko1221#2161 Niko1221#2287. Engine: Niko1221#2253 Niko1221#2265 Niko1221#2247 Niko1221#2217 Niko1221#2243.
New opt-in engine flags: --session-state-codec (enabled in the local configs), --conversation-cache-park-gain and --drop-file-cache (left off: no measured benefit on the RX 7600 XT box). Bench: bench/results/upstream-prs-2026-10-13.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
later-3 added a commit to later-3/Strata that referenced this pull request Oct 14, 2026
…e (and mirror it in the disk cache) so Niko1221#2265's park-gain works in disk mode; drop a stray line
later-3 added a commit to later-3/Strata that referenced this pull request Oct 15, 2026
…e (and mirror it in the disk cache) so Niko1221#2265's park-gain works in disk mode; drop a stray line

(cherry picked from commit 8e6b4d6)
Niko1221 added a commit that referenced this pull request Oct 17, 2026
Niko1221 added a commit that referenced this pull request Oct 17, 2026
…ne borrows it, the parked conversation stays (#1164)

Sibling subagents with the same system prompt and tools no longer cost each other their history: only the K/V up to the checkpoint and the checkpoint itself are copied into the session (conversation_snapshot_restore_prefix); the parked conversation stays where it is and is pinned while the outgoing one parks. A match on a parked conversation's live state or newest checkpoint is that conversation going on and is taken as before.

Rebased onto 0.1.44.1 by hand: the pinned shared prefix (#879) and evict_oldest() now also skip the borrowed donor, serials follow every erase, and park-gain (#2265) and the pin= sibling rule gate the outgoing park.

Co-authored-by: BlueKingMuch <53972523+BlueKingMuch@users.noreply.github.com>
@Niko1221

Copy link
Copy Markdown
Owner

Thank you, this is in for 0.1.45 as an opt-in with your authorship; I added the docs line. On our RTX 3060 with a 12.5K-token conversation whose client trims the reply each turn, turns 2-8 went from 6.06 s to 5.07 s with --conversation-cache-park-gain 500 (3 of 4 rounds faster), same output.

MistVVK added a commit to MistVVK/XeStrata that referenced this pull request Oct 18, 2026
Niko1221#2264・Niko1221#2265、upstream d9cb22d)

数百トークンしか進んでいない会話も、毎ターン丸ごとのスナップショットを書き、次のターンが
置き換えて捨てていた(upstream の報告: 1 つの長い会話で 1,418 回、2,252 GB の写し)。
置き換える前のコピーから N トークン進んでから置き直す。既定 0 は毎ターン置く。
@Niko1221

Copy link
Copy Markdown
Owner

Thanks for the pull request.

Your change is already in main for 0.2.0-beta, with your credit, so there is nothing left for you to do here. We're closing it because we're resetting the tracker for 0.2.0-beta: there are more than 1,300 open issues and pull requests, and we're closing everything that isn't being worked on right now.

If part of your work did not make it in and you want it considered, open a new pull request on top of main that follows CONTRIBUTING.md, or comment /reopen after fixing the title area prefix and the template.

@Niko1221 Niko1221 closed this Oct 19, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

2 participants