Guides

Reducing Claude Code token usage

Claude Code charges by tokens, and tokens scale with context size: every request resends the whole conversation, so a long session gets more expensive per message even if you're not doing more work. Most of the fix is keeping context small on purpose instead of letting it grow by default.

See what's actually in context

Before trimming anything, look at where the tokens go:

Clear between unrelated tasks

/clear starts a fresh session with empty context. Stale history from a finished task doesn't help the next one, it just gets resent (and re-billed) on every following message.

/rename fix-login-bug
/clear

/rename first so you can find the old session again with /resume if you need it. Session cost tracking in /usage resets on /clear too, so it's also the easiest way to tell how much a task actually cost.

Compact with intent, not by accident

/compact summarizes older conversation history to free up space. Left to itself it decides what's worth keeping; you can steer it instead:

/compact Focus on code samples and API usage, drop exploratory dead ends

You can set a standing default in CLAUDE.md:

## Compact instructions

When compacting, keep test output and code changes.
Drop file-exploration steps that didn't lead anywhere.

Note that compaction itself is a large request — it has to read the whole conversation to summarize it. If you just want a clean break, /clear is free where /compact isn't.

Keep CLAUDE.md small, push detail into skills

CLAUDE.md loads into every session's context, even sessions that never touch the workflow it describes. Detailed, occasional instructions (a migration checklist, a release process) belong in a skill instead, which loads only when invoked. Aim to keep CLAUDE.md itself under roughly 200 lines of genuinely load-bearing project context.

Push noisy work into subagents

Running a test suite, fetching docs, or grepping through logs can produce thousands of lines of output. A subagent absorbs that noise in its own context window and returns only a summary to the main conversation:

---
name: test-runner
description: Runs the test suite and returns a diagnosis instead of raw logs.
tools: Read, Grep, Glob, Bash
model: haiku
---

Run the project's tests. For each failure, report file:line, cause and a
suggested fix in a few lines. Never paste raw log output back.

The model: haiku line matters on its own: mechanical, well-specified work like "run this command and classify the output" doesn't need your main model's price tag.

Filter noise before it reaches Claude at all

A hook can preprocess tool output before it ever enters context. Instead of Claude reading a 10,000-line log to find the failure, a PreToolUse hook can rewrite the command to grep for errors first:

#!/bin/bash
input=$(cat)
cmd=$(echo "$input" | jq -r '.tool_input.command')
if [[ "$cmd" =~ ^(npm test|pytest|go test) ]]; then
  filtered="$cmd 2>&1 | grep -A 5 -E '(FAIL|ERROR|error:)' | head -100"
  echo "$input" | jq --arg f "$filtered" \
    '{hookSpecificOutput: {hookEventName: "PreToolUse", permissionDecision: "allow", updatedInput: (.tool_input + {command: $f})}}'
else
  echo "{}"
fi

If you'd rather not hand-write the JSON, the free hook builder generates hook scripts like this from a plain description of what you want blocked or filtered.

Cut MCP overhead

MCP tool definitions are deferred by default in current Claude Code versions, so only tool names enter context until a tool is actually used — but server instructions and any tools you do use still cost tokens. Run /mcp to see configured servers and disable ones you're not using in the current project. Where a CLI already exists (gh, aws, gcloud), it's often more context-efficient than the equivalent MCP server, since a CLI adds no per-tool listing at all.

Match the model, and the thinking budget, to the task

LeverCommandWhen
Session model/modelSonnet for most coding; reserve Opus for hard architectural or multi-step reasoning
Subagent modelmodel: haiku in the agent's frontmatterMechanical, well-specified subagent tasks
Reasoning effort/effortSimple tasks that don't need deep extended thinking
Thinking budgetMAX_THINKING_TOKENS env varModels with a fixed (non-adaptive) thinking budget

Switching to Opus mid-session also raises the model subagents inherit by default, so a model change at the top of a session has a bigger effect than it looks like.

Write specific prompts

"Improve this codebase" triggers broad exploration: Claude has to read widely just to figure out what you mean. "Add input validation to the login handler in auth.ts" lets it go straight to the relevant file. The gap between those two isn't style, it's tokens.

Skip the setup: get the tested versions

Keelwork bundles 10 workflow skills, 5 tested safety hooks (including a full guard-bash and a secret scanner), 3 subagents and 5 CLAUDE.md templates, with a one-command installer that safely merges into your settings.

Get Keelwork — $24 →