Claude Code - Using Context More Efficiently
I’m trying to use Claude Code’s context more efficiently on long sessions. Anthropic published a much more thorough guide on the same topic the day before I wrote this: Maximizing the value of your Claude Code sessions, covering things like /clear between tasks, @-mentioning files instead of naming them, and keeping /model and /effort settled so you don’t bust the prompt cache. Worth reading first. Two things I’ve been doing on top of it: a Stop hook that warns me when a session’s context gets too long, and a small skill for handing off work before it’s even started.
The hook fires after every response, so it can catch a session getting bloated before I notice the agent acting slower or worse:
{
"hooks": {
"Stop": [
{
"hooks": [
{
"type": "command",
"command": "jq -r '.transcript_path' | { read -r t; tail -n 200 \"$t\" | jq -s -r '[.[] | select(.type==\"assistant\" and .message.usage != null)] | last as $l | if $l == null then empty else (($l.message.usage.input_tokens // 0) + ($l.message.usage.cache_creation_input_tokens // 0) + ($l.message.usage.cache_read_input_tokens // 0)) as $tot | if $tot > 150000 then {systemMessage: (\"Context ~\" + (($tot/1000)|floor|tostring) + \"k tokens this turn (over 150k). Consider /compact, or say create handoff and start a fresh session.\")} else empty end end'; } 2>/dev/null || true"
}
]
}
]
}
}
The transcript is JSONL, one message per line, so tail -n 200 finds the most recent assistant turn without scanning the whole file. The hook is read-only, so it just parses that file locally with jq and never talks to the model. What it’s reading is accounting the API already produces on every turn, hook or not. usage splits input tokens by whether they came from the prompt cache: input_tokens for what got processed fresh, cache_creation_input_tokens for what got newly cached, cache_read_input_tokens for what got served from an earlier turn’s cache. All three are still part of the model’s actual context for that turn, so summing just input_tokens badly undercounts a long session, where most of the history is being read from cache rather than reprocessed fresh. Past 150k the hook prints a systemMessage. Claude Code shows that inline without sending it back to the model, so even the warning itself costs nothing (hooks reference).
A warning is only useful if there’s a good next step, and “just start a new chat” throws away real, unplanned-for work. Most of the time that means handing off work before it’s even started, not resuming something already underway. So I wrote kickoff, and kept the whole thing to one paragraph:
Write it as a prompt for the next session, not a document for a human. That agent has the same repo access you do, so don’t summarize or quote code; point at the files and areas that matter and let it read them itself. Include the actual task, why it matters, and whatever took real investigation to establish, especially constraints or dead ends already found. End on the first concrete action, specific enough to act on without re-deriving it.