The occupancy trigger compacts context without knowing how many calls are left
· 6 min read
When an agent’s conversation gets close to the context limit, something has to replace the history with a shorter summary. That is compaction, and the usual trigger is occupancy: compact when the window reaches a certain fill level.
The arithmetic
On call i of a turn that will end up making N calls in total:
cost C = fixed, 30–60k weighted tokens
(the summarisation call, plus re-caching the new prefix)
saving s = (ctx_before − ctx_after) × cache_read_weight
...earned once per call that remains
balance = s·(N − i) − C
Weighted tokens count each token by how it is billed: writing to the cache costs 1.25× and reading from it 0.1×. So compaction pays if and only if:
N − i > C / s
On 15 Sept I measured 13 compactions call by call. A compaction paid for itself when what it saved over the following calls exceeded what it cost. With 17 or more calls left, 4 of 4 paid. With 9 or fewer, 7 of 7 didn’t. The two in between, with 11 and 16 calls left, landed within 6k weighted tokens of break-even, one on each side. With 13 points, 17 is approximate and specific to my system.
Whether compacting pays, by calls remaining
Balance in units of the per-call saving. Above the line it pays; below, it does not.
FIG. 1 · The threshold is arithmetic; the markers are the observed record. The trigger in use keys on context occupancy, which does not know how many calls remain.
Why occupancy can’t decide it
The inequality needs N, and nothing in the turn says how much work is left. Occupancy tracks
i, how far in the turn is, but not N − i, how far there is to go. A turn at 80% of its
context may have thirty calls left or two, and the trigger does the same thing in both.
Estimating what’s left
N − i can be estimated from data the system already keeps: one row per turn, with the tool
calls that turn made. The estimate is the residual mean lifetime:
m_role(i) = E[ N − i | N > i ]
If a role is already i calls in, how many does it have left on average. Actuaries use the same
statistic for life expectancy at a given age. The rule becomes compact ⟺ m_role(i) > C/s, and
both sides come out of the log.
| Role | n | Mean | p50 | at i=5 | at i=10 | at i=15 | at i=20 | at i=30 |
|---|---|---|---|---|---|---|---|---|
| front-end dev | 229 | 51.5 | 52 | 50.3 | 46.4 | 43.6 | 40.4 | 34.8 |
| panel dev | 27 | 34.3 | 30 | 33.1 | 34.0 | 32.4 | 29.2 | 26.5 |
| mobile dev | 204 | 32.8 | 26 | 30.8 | 27.4 | 25.9 | 25.2 | 25.8 |
| platform dev | 167 | 33.5 | 36 | 35.2 | 30.2 | 25.2 | 21.1 | 14.5 |
| back-end dev | 394 | 31.7 | 32 | 31.1 | 26.4 | 22.4 | 19.0 | 15.1 |
| second back-end dev | 180 | 29.8 | 31 | 27.8 | 23.6 | 19.6 | 16.7 | 11.5 |
| auditor | 277 | 27.9 | 26 | 23.8 | 19.6 | 18.8 | 16.8 | 12.6 |
| manager | 487 | 21.4 | 19 | 20.5 | 18.7 | 16.3 | 15.5 | 13.3 |
| qa | 582 | 19.3 | 16 | 18.8 | 16.3 | 14.7 | 14.3 | 14.1 |
| architect | 207 | 23.5 | 22 | 19.1 | 15.3 | 12.2 | 10.9 | 7.4 |
| operations | 224 | 13.8 | 10 | 13.1 | 13.0 | 12.5 | 12.7 | 12.0 |
| reviewer | 280 | 11.0 | 8 | 7.5 | 8.1 | 8.4 | 10.0 | 5.1 |
| infrastructure | 88 | 12.4 | 8 | 7.9 | 10.6 | 8.0 | 5.9 | 4.0 |
TABLE 1 · Expected remaining tool calls once the turn has made i of them. n: the role’s turns with at least one tool call (3,346 across these 13 roles). Mean and p50: tool calls per turn. Bold: above the ~17 break-even.
For the heavy roles the estimate barely drops. A front-end dev thirty calls in still has 34.8 left on average, more than a light role makes in a whole turn. And it varies a lot by role: ten calls in, one expects 46.4 more and another 8.1. That’s why I estimate per role instead of using one threshold for everyone.
The rule isn’t applied yet: the trigger is still occupancy-based, and everything here comes from turns that already happened.
In production
By 17 Sept the production log had 80 compactions:
| Count | Average per compaction (weighted tokens) | |
|---|---|---|
| Paid for itself | 24 (30%) | +311,030 |
| Did not | 56 (70%) | −30,326 |
| Net | +5,766,484 |
Only 3 in 10 paid, but one hit was worth about ten misses, so the net was positive. This log doesn’t record how many calls were left at each compaction, so it neither confirms nor refutes the 17-call crossover. Next I want to know which long-turn roles to switch it on for.
How this was measured. 13 compactions measured call by call on 15 Sept 2026, 80 recorded in production by 17 Sept, and the 3,948-turn log of eight agent teams. Read-only analysis: I spent no model tokens producing these numbers.
Related
- In a small test, keeping an agent's thread alive cost less than resetting it Resetting a role's thread every turn looked like the way to spend fewer tokens. In a controlled test with one role and one task, the long thread came out cheaper, because of cache writes.
- The nine-role team costs 3.5× more per verified task than the four-role one I compared eight agent teams on cost per verified task. The gap follows tool calls per turn, and splitting the large team would not change what its two most expensive roles do.