Documentation menu
Long-running sessions: context tracking and rotation
Coding agents slow down, forget instructions and eventually fail once their context window fills up. nid watches how full each session's context is and rotates the conversation before that happens, without losing the session's place in the team.
What nid tracks#
Each session has a context record (see Session in the API reference):
| Field | Meaning |
|---|---|
used | Tokens in the context window after the agent's last model call |
size | The context window size, when the agent reports it |
turns | Turns since the conversation started or was last rotated |
rotations | Rotations so far, with the last one's time, method and reason |
Where the numbers come from:
| Agent | used | size |
|---|---|---|
| Claude Code | the latest assistant message's usage (input + cache creation + cache read + output); subagent messages are ignored | the result's modelUsage[*].contextWindow |
| Codex | thread/: last | modelContextWindow |
| ACP agents (opencode, kimi, custom ACP) | usage | usage |
| PTY / custom terminal agents | not reported | not reported |
Agents that report nothing still rotate on maxTurns and with nid rotate.
You can see it in:
nid ls: theCONTEXTcolumn (62% of 200k, yellow from 75%,↻2after two rotations);- the dashboard: a context meter on the session page and
ctx 62% of 200kin the group's session table.
Rotation#
A rotation happens after a turn ends when the group's policy says it is due, when the human runs
nid rotate <session> (or presses Rotate on the session page), or when the agent calls the
handoff_write tool by itself. There are two methods:
Compaction (compact): nid asks the agent to compact its own conversation, keeping the same
vendor session: Claude Code gets /compact, Codex gets thread/. This is the cheaper
method: the agent keeps a summary of everything it knew and does not have to re-read files.
Handoff (handoff):
- nid sends the agent one turn asking it to call
handoffwith a self-contained handoff (tasks held, what is done, next steps, decisions, gotchas). If the agent already called_write(summary) handoff_writeon its own, this step is skipped. - nid stops the agent process and starts a fresh vendor conversation on the same nid session: same session id, worktree, branch, claimed tasks and locks.
- The fresh conversation's first message is the handoff plus the current board (what
board_readshows). If the agent never wrote a handoff, its last output is used instead and the message says so.
Every rotation is recorded as a rotation event (↻ in nid watch, the dashboard feed and
transcript) with the method, the reason, and for a handoff the old and new vendor conversation ids
and the summary. A failed rotation is recorded too and reported to the human inbox; a failed
compaction in auto mode falls back to a handoff.
Rotations are paused while the group's budget is exhausted (they cost a turn); nid rotate still works.
Configuration#
Set rotate on a group in nid.yaml:
groups:
web:
goal: Add dark mode to the settings page
rotate:
mode: auto # auto | compact | handoff | off (default auto)
contextPercent: 80 # rotate when the context window is this full (default 85)
maxTurns: 60 # also rotate after this many turns in one conversation (default: never)
sessions:
- agent: claude
name: lead
- agent: codex
or on a running group: nid group set web rotate='{"mode":"handoff","maxTurns":40}'.
mode | Behaviour |
|---|---|
auto | The agent's own compaction when its driver has one (Claude Code, Codex), else a handoff |
compact | Compaction only; agents without compaction get a handoff |
handoff | Always a handoff into a fresh conversation (the most predictable context size, costs a re-read) |
off | Never automatically; nid rotate and agent-initiated handoff_write still work |
Choosing: compaction is cheaper and keeps the agent's working memory, but the vendor decides what
to keep and repeated compactions can drift. A handoff gives a clean slate and forces the agent to
write down its state, which also leaves a readable record in the event log. For very long runs,
mode: auto with a maxTurns limit is a good default; use handoff when you want the record.
Forcing a rotation#
nid rotate web/worker # the group's mode (auto when the group says off)
nid rotate web/worker --mode handoff
An idle session rotates at once; a working (or rate-limited) session rotates when its current turn
ends. HTTP clients call session.
Agents writing their own handoff#
Every agent has the handoff tool. Calling it outside a rotation means "my context
is cluttered: start me fresh from this summary when this turn ends". nid then rotates with that
summary and does not ask again.