2026-01-07 18:03:35 +01:00
---
2026-02-09 14:20:56 -08:00
title: "Session Pruning"
2026-01-08 22:23:03 +01:00
summary: "Session pruning: tool-result trimming to reduce context bloat"
2026-01-07 18:03:35 +01:00
read_when:
- You want to reduce LLM context growth from tool outputs
2026-01-09 12:44:23 +00:00
- You are tuning agents.defaults.contextPruning
2026-01-07 18:03:35 +01:00
---
2026-02-01 20:04:53 +05:30
2026-01-07 18:03:35 +01:00
# Session Pruning
2026-01-08 22:23:03 +01:00
Session pruning trims **old tool results** from the in-memory context right before each LLM call. It does **not** rewrite the on-disk session history (`*.jsonl` ).
2026-01-07 18:03:35 +01:00
## When it runs
2026-02-01 20:04:53 +05:30
2026-01-21 19:44:20 +00:00
- When `mode: "cache-ttl"` is enabled and the last Anthropic call for the session is older than `ttl` .
2026-01-07 18:03:35 +01:00
- Only affects the messages sent to the model for that request.
2026-02-01 20:04:53 +05:30
- Only active for Anthropic API calls (and OpenRouter Anthropic models).
2026-02-23 18:45:30 +00:00
- For best results, match `ttl` to your model `cacheRetention` policy (`short` = 5m, `long` = 1h).
2026-02-01 20:04:53 +05:30
- After a prune, the TTL window resets so subsequent requests keep cache until `ttl` expires again.
2026-01-07 18:03:35 +01:00
2026-01-21 20:23:30 +00:00
## Smart defaults (Anthropic)
2026-02-01 20:04:53 +05:30
2026-01-21 20:23:30 +00:00
- **OAuth or setup-token** profiles: enable `cache-ttl` pruning and set heartbeat to `1h` .
2026-02-23 18:45:30 +00:00
- **API key** profiles: enable `cache-ttl` pruning, set heartbeat to `30m` , and default `cacheRetention: "short"` on Anthropic models.
2026-01-30 03:15:10 +01:00
- If you set any of these values explicitly, OpenClaw does **not** override them.
2026-01-21 20:23:30 +00:00
## What this improves (cost + cache behavior)
2026-02-01 20:04:53 +05:30
2026-01-21 20:23:30 +00:00
- **Why prune:** Anthropic prompt caching only applies within the TTL. If a session goes idle past the TTL, the next request re-caches the full prompt unless you trim it first.
- **What gets cheaper:** pruning reduces the **cacheWrite** size for that first request after the TTL expires.
- **Why the TTL reset matters:** once pruning runs, the cache window resets, so follow‑ up requests can reuse the freshly cached prompt instead of re-caching the full history again.
- **What it does not do:** pruning doesn’ t add tokens or “double” costs; it only changes what gets cached on that first post‑ TTL request.
2026-01-07 18:03:35 +01:00
## What can be pruned
2026-02-01 20:04:53 +05:30
2026-01-07 18:03:35 +01:00
- Only `toolResult` messages.
- User + assistant messages are **never** modified.
- The last `keepLastAssistants` assistant messages are protected; tool results after that cutoff are not pruned.
- If there aren’ t enough assistant messages to establish the cutoff, pruning is skipped.
- Tool results containing **image blocks** are skipped (never trimmed/cleared).
## Context window estimation
2026-02-01 20:04:53 +05:30
2026-02-01 19:49:35 +05:30
Pruning uses an estimated context window (chars ≈ tokens × 4). The base window is resolved in this order:
2026-02-01 20:04:53 +05:30
1. `models.providers.*.models[].contextWindow` override.
2. Model definition `contextWindow` (from the model registry).
3. Default `200000` tokens.
2026-01-31 21:13:13 +09:00
2026-02-01 19:49:35 +05:30
If `agents.defaults.contextTokens` is set, it is treated as a cap (min) on the resolved window.
2026-01-07 18:03:35 +01:00
2026-01-21 19:44:20 +00:00
## Mode
2026-02-01 20:04:53 +05:30
2026-01-21 19:44:20 +00:00
### cache-ttl
2026-02-01 20:04:53 +05:30
2026-01-21 19:44:20 +00:00
- Pruning only runs if the last Anthropic call is older than `ttl` (default `5m` ).
- When it runs: same soft-trim + hard-clear behavior as before.
2026-01-07 18:03:35 +01:00
## Soft vs hard pruning
2026-02-01 20:04:53 +05:30
2026-01-07 18:03:35 +01:00
- **Soft-trim**: only for oversized tool results.
- Keeps head + tail, inserts `...` , and appends a note with the original size.
- Skips results with image blocks.
- **Hard-clear**: replaces the entire tool result with `hardClear.placeholder` .
## Tool selection
2026-02-01 20:04:53 +05:30
2026-01-07 18:03:35 +01:00
- `tools.allow` / `tools.deny` support `*` wildcards.
- Deny wins.
2026-01-09 05:54:34 +01:00
- Matching is case-insensitive.
2026-01-07 18:03:35 +01:00
- Empty allow list => all tools allowed.
## Interaction with other limits
2026-02-01 20:04:53 +05:30
2026-01-07 18:03:35 +01:00
- Built-in tools already truncate their own output; session pruning is an extra layer that prevents long-running chats from accumulating too much tool output in the model context.
2026-01-07 18:12:17 +01:00
- Compaction is separate: compaction summarizes and persists, pruning is transient per request. See [/concepts/compaction ](/concepts/compaction ).
2026-01-07 18:03:35 +01:00
## Defaults (when enabled)
2026-02-01 20:04:53 +05:30
2026-01-21 19:44:20 +00:00
- `ttl` : `"5m"`
2026-01-07 18:03:35 +01:00
- `keepLastAssistants` : `3`
- `softTrimRatio` : `0.3`
- `hardClearRatio` : `0.5`
- `minPrunableToolChars` : `50000`
- `softTrim` : `{ maxChars: 4000, headChars: 1500, tailChars: 1500 }`
- `hardClear` : `{ enabled: true, placeholder: "[Old tool result content cleared]" }`
## Examples
2026-02-01 20:04:53 +05:30
2026-01-21 19:44:20 +00:00
Default (off):
2026-02-01 20:04:53 +05:30
2026-01-08 22:23:03 +01:00
```json5
{
2026-02-23 18:45:30 +00:00
agents: { defaults: { contextPruning: { mode: "off" } } },
2026-01-08 22:23:03 +01:00
}
```
2026-01-21 19:44:20 +00:00
Enable TTL-aware pruning:
2026-02-01 20:04:53 +05:30
2026-01-07 18:03:35 +01:00
```json5
{
2026-02-23 18:45:30 +00:00
agents: { defaults: { contextPruning: { mode: "cache-ttl", ttl: "5m" } } },
2026-01-07 18:03:35 +01:00
}
```
Restrict pruning to specific tools:
2026-02-01 20:04:53 +05:30
2026-01-07 18:03:35 +01:00
```json5
{
2026-02-23 18:45:30 +00:00
agents: {
defaults: {
contextPruning: {
mode: "cache-ttl",
tools: { allow: ["exec", "read"], deny: ["*image*"] },
},
2026-02-01 20:04:53 +05:30
},
},
2026-01-07 18:03:35 +01:00
}
```
See config reference: [Gateway Configuration ](/gateway/configuration )