Repository navigation
Description
Conversation cache is not reused with OpenClaw agent loops: full 150K–168K prompt is re-read on every request
Description
I am using Strata as an OpenAI-compatible backend for OpenClaw.
In a long-running OpenClaw agent session with tool calls, Strata appears to re-read the entire prompt on almost every request instead of resuming from a conversation-cache checkpoint.
The prompt is currently around 150K–168K tokens, so this adds roughly 100+ seconds of prompt processing before nearly every agent/tool step.
I understand that Strata currently caches one conversation at a time, and that a checkpoint can only be reused when the new prompt starts with exactly the cached tokens/images. However, this workload appears to be a continuous OpenClaw agent/session, so I would like to understand why no useful checkpoint is being reused.
Environment
- OS: Ubuntu 22.04.5 LTS
- GPU: NVIDIA RTX A4500 20 GB, SM86
- NVIDIA driver: 580.173.02
- CPU: Intel Xeon w3-2435, AVX-512
- RAM: 377 GB
- Model: Qwen3.8-Flash-Next IQ3_S
- Context: 262144
- KV: int8
- Client: OpenClaw using the OpenAI-compatible API
- Current source test: v0.1.24
- Local engine build: CUDA 13.0 / SM86
I initially noticed this while testing newer prompt-performance builds as well.
Actual behavior
A typical sequence looks like this:
[strata] reading the prompt: 8,192 of 152,110 tokens, 4 s so far
...
[strata] reading the prompt: 152,105 of 152,110 tokens, 99 s so far
...
[strata] done: 2342 tokens in 145 s, expert cache 86.4% hit
[strata] reading the prompt: 8,192 of 152,773 tokens, 4 s so far
...
[strata] reading the prompt: 152,768 of 152,773 tokens, 98 s so far
...
[strata] done: 1026 tokens in 118 s, expert cache 82.1% hit
The same pattern continues as the conversation grows:
154K prompt -> full reread
156K prompt -> full reread
158K prompt -> full reread
160K prompt -> full reread
162K prompt -> full reread
164K prompt -> full reread
166K prompt -> full reread
168K prompt -> full reread
I do not see a useful RESUME from the existing long prefix. Each request starts prompt processing again from the first chunk.
For example, a ~168K request still takes about 112 seconds just to finish reading the prompt before generation starts.
Expected behavior
For an agent loop where most of the system prompt, tool definitions, conversation history, and previous tool calls are unchanged, I expected Strata to resume from a long matching checkpoint and process only the newly appended part.
Something conceptually like:
previous request: 160K tokens
next request: 162K tokens
RESUME ~150K-160K
prefill only the changed/new suffix
rather than re-reading all ~162K tokens.
If OpenClaw changes something early in the serialized prompt on every request, then perhaps this is expected behavior. In that case, it would be very useful if Strata could report why the conversation-cache match failed (for example: checkpoint considered, matching-prefix length, or first mismatch position).
Secondary observation: expert-cache hit rate
In the same workload, decode expert-cache hit rate is generally lower than I observed in earlier runs.
Across 22 requests from this log:
- mean: ~82.4%
- median: ~83.7%
- range: 68.7%–87.5%
I previously saw values close to ~90% much more consistently on the same machine/model.
Examples:
expert cache 86.4% hit
expert cache 82.1% hit
expert cache 84.8% hit
expert cache 81.7% hit
expert cache 74.6% hit
...
expert cache 68.7% hit
...
expert cache 77.6% hit
expert cache 76.9% hit
I am not sure whether this is related to the prompt/cache behavior or is an independent adaptive-expert-cache effect, so I am mentioning it only as a secondary observation.
Questions
- Is OpenClaw known to serialize OpenAI-compatible requests in a way that prevents Strata's exact-prefix conversation-cache matching?
- Is there a way to log the matching prefix/checkpoint selected for each request, or the reason a checkpoint was rejected?
- Would supporting a stable
prompt_cache_key/ session identifier help Strata preserve the appropriate conversation branch for agent workloads? - Is there any configuration I should change for this workload (
--prompt-cache,--prompt-cache-every,--turn-token, etc.)?
I can provide the full Strata log and request/config details if useful.
Activity
Anhelone commentedon Sep 29, 2026
Hi! I have a feature idea that could be very useful for long-context agent workflows.
Right now my typical setup looks like this:
MAIN agent: ~150K context
↓
switch to subagent: ~30–60K context
↓
return to MAIN
The problem is that when returning to MAIN, a large part of the 150K context may need to be processed again.
With prompt processing around 1000–1800 tok/s, rebuilding 150K tokens takes roughly:
1000 tok/s → ~150 sec
1500 tok/s → ~100 sec
1800 tok/s → ~83 sec
So one MAIN → subagent → MAIN switch can cost around 1–2.5 minutes.
Would it be possible to add an explicit save/restore API for conversation state?
For example:
POST /sessions/main/save
POST /sessions/main/restore
or something similar to llama.cpp slot save/restore.
Then an agent system could do:
MAIN 150K
↓
save MAIN state to SSD
SUBAGENT 50K
↓
work normally
restore MAIN state
↓
continue from the same context
If restoring the saved state from a fast NVMe SSD took, for example, 5–15 seconds instead of reprocessing 80–150 seconds of prompt, that would make switching between agents much faster.
It would also make it possible to keep several large agent sessions without keeping all of them active in RAM/VRAM:
MAIN 150K
Coder agent 80K
Research agent 60K
Only the active one would stay in memory, while inactive conversation states could be stored on SSD and restored when needed.
Ideally this could also survive a Strata restart.
Maybe the existing RAM conversation cache could remain the fast first level, while saved conversation states on SSD act as a second level.
This would be especially useful for Hermes, OpenClaw, Cline and other systems where a main agent frequently delegates work to subagents and then resumes its previous long context.
Would something like persistent conversation-state save/restore fit Strata’s architecture?
Niko1221 commentedon Sep 29, 2026
Strata reuses a checkpoint only when the new prompt starts with exactly the same tokens, and it keeps one conversation. So either OpenClaw changes something early in the prompt (a date or a dynamic block in the system prompt), or other requests (subagents, compaction) run in between and replace the cached conversation. Could you share a few consecutive
prompt N tokens = R reusedlines from the log? We'll add a log line showing where the prompts first differ; multi-conversation caching and save/restore are tracked in #57.Niko1221 commentedon Sep 30, 2026
Closing since we haven't heard back. If you can share a few consecutive
prompt N tokens = R reusedlines, please reopen or open a new issue. Multi-conversation caching is tracked in #57 (and #189 implements it).q738531569-tech commentedon Oct 27, 2026
Found it on my box — and the cause was
--conversation-cache-*(parking), not the client.I have a 2× V100-16GB box running Qwen3.8-Flash-Next IQ3_XXS at 524288 context. Same symptom as @jinkang06: a long agent session re-reads the whole prompt on most steps. But mine came and went, so I could compare days.
What I did: for each day, I took every
reading the prompt: START of TOTALline from the journal and computedTOTAL - START— how many tokens actually had to be read. Then I took the median.That is a 2,000× difference in the same session, same model, same context size. The only parameter that changed is parking.
The engine log shows what parking does on every single turn:
So on a plain continuing conversation — one session, nothing else running — parking still copies the outgoing conversation's checkpoints and K/V into host RAM, then the next request brings them back.
DETAILS.mdcalls parking "a switch-time decision", but the engine treats every request as a switch: the conversation that just finished has to be parked before the next one goes in.My guess at why that kills reuse: the copy out and the copy back are not free.
conversation_checkpoints_split/mergemove the checkpoint list around, and a failed merge doeschecks.clear()(generate.cpp, theMergeBackdestructor). Restore then re-validates every checkpoint — it must be an exact token prefix, and"checkpoint image identity differs"/"checkpoint image prefix differs"are hard failures that make the whole snapshotConversationRestore::invalid. One mismatch and you fall back to a normal full read. Related: #3928 already documented thatresume == 0triggerschecks.clear()on the next request.With parking off, the same session is fine:
95-99% reuse, prefill 0.5-2.2 s.
So, two answers for the original question:
--conversation-cache-mibsmaller than your snapshots: [Engine] Stop during a long prompt read loses the read prefix; the next message re-reads 375K tokens (22 min) #3928 shows a 6.9 GiB snapshot against a 3.84 GiB budget silently degrading to a full read.@Niko1221 — if this matches your model of the code, the useful doc line would be something like: "A single conversation that never switches gains nothing from parking and should leave
--conversation-cache-mibat 0; on some boxes each turn pays a full snapshot copy plus a restore validation."Box for reference: 2× Tesla V100-SXM2-16GB,
--peer-device 1, engine 0.1.47,--max-context 524288 --kv int8 --kv-resident 32768 --prompt-cache 64 --prompt-cache-spread, 125 GB RAM, session 290K-330K tokens. Numbers above come from the normal engine log over four days, not a controlled benchmark.