finance
The Practitioner's Toolkit: Managing Your AI Token Consumption
Token Economics Series: Part 1: Your AI Bill Is Lying to You | Part 2: The Practitioner’s Toolkit | Part 3: Scaling the Discipline | Cheat-Sheet
You can’t manage what you can’t see. This is the practical guide to visibility and control over AI inference consumption — the specific levers, commands, and patterns that turn token spend from an invisible burn into a managed resource. I’ll use Claude Code as the concrete example throughout, because it’s what I use daily and it exposes more control surface than most tools, but the principles transfer to any LLM tooling you’re working with.
Visibility First — You Can’t Manage What You Can’t Measure
In Part 1, I laid out the argument that token management is a professional discipline, not an afterthought. I introduced the skill stack — visibility, control, architecture, culture — and argued you can’t skip steps. Visibility is step one because everything else depends on it.
Most people have no idea what they’re spending per task. They know their monthly bill. They might know their daily average. But ask them what a debugging session costs versus a code generation session, or how much context they’re carrying at any given moment, and you get a blank stare.
That blank stare is where the waste lives.
There are three levels of visibility, and you want all of them.
Real-Time: What’s Happening Right Now
The fastest feedback loop is the one you never have to ask for. In Claude Code, that means the status line — a persistent display at the bottom of your terminal that shows cost, context fill, and model information as you work.
The /cost command gives you the current session’s spend: dollar amount, API duration, wall duration, lines added and removed. The /context command is arguably more useful — it breaks down your context window by category (files, tools, MCP, history, system prompt) and tells you what percentage you’ve used. It even offers optimisation suggestions. Between these two commands, you can see both what you’ve spent and what you’re about to spend.
This is the equivalent of a runner glancing at their watch mid-race. Not to obsess over the number, but to know whether they’re on pace.
Session: The Rich Data
The real analytical power lives in the JSONL logs. Every Claude Code session writes a detailed log to ~/.claude/projects/<encoded-directory>/*.jsonl — one JSON object per event. User messages, assistant messages (with full usage breakdowns), tool calls, tool results, metadata. It’s comprehensive.
If you want to actually understand your consumption patterns, this is where you go. And the easiest way to query it is with DuckDB, which can read JSONL natively:
SELECT * FROM read_json_auto('session.jsonl')
That single line gives you a queryable table of everything that happened in a session. From there, you can slice by model, by token type (input, output, cache read, cache creation), by tool, by time. You can calculate cost per tool call, identify which operations burn the most context, and spot the sessions where things went sideways.
There’s a catch, though: the default log retention is 30 days. After that, your logs are deleted. If you want to do any kind of historical analysis — and you should — extend this immediately:
{
"logRetentionDays": 100000
}
Set it in your settings.json and forget about it. The storage cost is negligible. The analytical value of having three months of session logs when you’re trying to understand spending trends is not.
Historical: Third-Party Tools
You don’t have to build your own analytics. The community has built several tools that parse JSONL logs into useful views:
| Tool | What it does |
|---|---|
| ccusage | Daily/monthly/session reports, model breakdown, status line integration. The most mature option. |
| Claude-Code-Usage-Monitor | Real-time terminal dashboard, burn rate predictions, P90 analysis. Good for spotting outlier sessions. |
| claudetop | Status line with live cost, cache efficiency metrics, plugin system with 8 extensions. |
These tools solve different problems. ccusage is best for trend analysis — what am I spending over time, broken down by model and period? Claude-Code-Usage-Monitor is best for real-time awareness — am I burning hot right now? claudetop sits in between, with its plugin system making it the most extensible.
The 200K Token Price Break
One visibility point that catches people off guard: Sonnet 4.6 has a pricing step function at 200,000 input tokens per request.
| Condition | Input Price | Output Price |
|---|---|---|
| Input up to 200K tokens | $3/MTok | $15/MTok |
| Input over 200K tokens | $6/MTok | $22.50/MTok |
That’s a doubling of input cost and a 50% increase in output cost once you cross 200K. This applies per-request — and in Claude Code, where your full context is re-sent with every message, a bloated context window doesn’t just cost more linearly. It costs more per token once you cross that threshold.
This is why context management matters so much, and why the 1M context window being available doesn’t mean you should fill it. Available and advisable are different things.
The Five Cost Levers
Once you can see what you’re spending, you need levers to change it. I’ve identified five distinct levers, each with different impact profiles and trade-offs. Most people know about one or two of these. Using all five together is what separates intentional spend from accidental waste.
Lever 1: Model Selection
This is the biggest single lever. The cost difference between models for the same task ranges from 10x to 100x. Haiku costs a fraction of Sonnet, which costs a fraction of Opus. And for many tasks — more than most people admit — the cheaper model produces identical results.
Claude Code gives you more model switching flexibility than most tools:
| Method | Scope | Details |
|---|---|---|
/model | Mid-session | Interactive picker with effort slider |
/model sonnet | Mid-session | Direct switch, skips the picker |
--model <name> | Session start | CLI flag: claude --model haiku |
ANTHROPIC_MODEL env var | All sessions | Environment variable override |
model in settings.json | Default | Set via /config — initial selection, not enforcement |
model: frontmatter | Per-subagent/skill | Each subagent or skill can run a different model |
opusplan alias | Session | Opus for planning, auto-switches to Sonnet for execution |
The key insight is that you don’t have to pick one model and stick with it. You can switch mid-session. You can run different models for different subagents. You can use Opus for the hard thinking and Sonnet for the execution. The opusplan alias does exactly this — Opus reasons about what to do, Sonnet does the work. You get frontier-quality planning with mid-tier execution costs.
I wrote a full framework for model decisions that goes deep on this. The short version: default to Sonnet for most coding work, drop to Haiku for simple tasks and quick questions, and reach for Opus only when you genuinely need the reasoning depth. Most people use Opus for everything because it’s the best. It is the best. It’s also 5-10x the cost, and for 80% of tasks, Sonnet produces the same result.
Lever 2: Effort and Thinking
Effort levels are a direct cost dial. They control how many thinking tokens the model spends before producing output — and thinking tokens are billed as output tokens, the most expensive token type.
Four levels: low, medium, high, and max (Opus only).
You can set effort via /effort mid-session, --effort at startup, the CLAUDE_CODE_EFFORT_LEVEL environment variable, or effortLevel in settings.json. Skills and subagents can also specify their own effort level in frontmatter, which means you can have a high-effort architecture discussion and a low-effort formatting task running at different cost points in the same session.
Here’s when to use what:
Low effort — straightforward edits, simple refactors, file operations, anything where the model doesn’t need to think. Fast and cheap. This is your default for “just do the obvious thing.”
Medium effort — general coding work. The default for Opus 4.6 and Sonnet 4.6, and the right level for most tasks. The model thinks enough to handle moderate complexity without burning tokens on deep reasoning you don’t need.
High effort — hard debugging, architectural decisions, complex refactoring across multiple files. When you need the model to really work through the problem. The thinking token spend goes up significantly, but so does the quality of reasoning.
Max effort — Opus only. No constraint on thinking token spend. Use this when you’re genuinely stuck and need the model to throw everything at the problem. I use max effort maybe once or twice a week. It’s powerful, but it’s expensive, and most problems don’t need it.
If you want to go further, you can disable thinking entirely with MAX_THINKING_TOKENS=0. This strips out all internal reasoning — the model just produces output directly. It’s fast, it’s cheap, and it works surprisingly well for simple tasks. For anything requiring actual thought, you’ll notice the quality drop immediately.
The cost difference between low and high effort on the same task can be substantial. A concrete example: I had a bug where a webhook handler was silently dropping events. With low effort, Sonnet suggested three possible causes and told me to check each one — reasonable, but it hadn’t actually thought through the code path. I’d have spent twenty minutes verifying each hypothesis. With high effort, Opus traced the full execution flow, identified that a middleware was consuming the request body before the handler could read it, and pointed to the exact line. One pass. Root cause found. The high-effort call cost roughly 4x the low-effort one. But the low-effort path would have cost me four calls plus the debugging time, making it more expensive in both tokens and minutes.
The skill isn’t always choosing the cheapest option. It’s choosing the right option for the task at hand.
Lever 3: Context Management
This is the lever that most people don’t realise they’re pulling — in the wrong direction — every single minute they use an AI coding tool.
Here’s the sentence that should change how you work: every token in your context window is re-sent with every message. That 150,000-token context you’ve built up over the last hour? You’re paying for all of it on every single exchange. That file you read forty minutes ago that’s no longer relevant? Still in context. Still being sent. Still costing money.
/compact is your primary hygiene tool. It summarises and compresses your conversation history, stripping out the detail you no longer need while preserving key decisions and code patterns. You can give it focus instructions — /compact Focus on the authentication refactor — to bias the summary toward what’s still relevant.
/clear is the nuclear option. Full context reset. Use it between completely unrelated tasks. If you’ve finished debugging the API and you’re about to start on the frontend, /clear is almost certainly the right move. Don’t carry dead context into a new problem. It costs money and it can confuse the model.
But here’s the trap that catches even disciplined practitioners: auto-compaction itself consumes tokens. When your context approaches the window limit, Claude Code automatically compacts. That compaction is an inference call — the model reads your entire context and produces a summary. One developer analysed their logs and found that roughly 80% of their session token usage was compaction. They were paying more for the model to summarise their work than they were paying for the model to do the work.
The fix is proactive compaction. Don’t wait for auto-compaction to trigger. Compact manually when you hit natural breakpoints — after finishing a feature, after a debugging session, after any task boundary. Smaller, more frequent compactions are cheaper than one massive auto-compaction of a bloated context.
And the 1M context window? Available on both Opus and Sonnet, automatic on Max/Team/Enterprise plans. It’s genuinely useful for tasks that need a lot of context — large codebase exploration, complex architectural reasoning across many files. But “available” doesn’t mean “fill it.” A 1M context window at $3/MTok means you could be sending $3 worth of input tokens on a single message. Keep individual requests under 200K input tokens where possible to avoid the pricing step-up, and think of the extended context as headroom for when you genuinely need it, not as space to fill.
For a deeper look at how to structure knowledge for agents without bloating context, see the piece on giving agents targeted knowledge.
Lever 4: Caching
Prompt caching is automatic in Claude Code — you don’t configure it. But understanding how it works is critical because it can save you 90% on repeated content, or cost you an unexpected premium if you don’t respect its mechanics.
Here’s how it works: when you send a request, content that matches previous requests (system prompts, CLAUDE.md, conversation history) is cached. Subsequent messages only pay the cache read price instead of the full input price.
The pricing difference is dramatic (Sonnet 4.6):
| Token Type | Price |
|---|---|
| Standard input | $3/MTok |
| Cache read | $0.30/MTok |
| Cache creation | $3.75/MTok |
Cache reads are 90% cheaper than standard input. That’s the good news. The cache creation premium — 25% above standard input — is the cost of establishing the cache. It pays for itself almost immediately if the content is reused, which in a typical session it is.
The critical constraint is the 5-minute TTL. If you pause for more than five minutes — a coffee break, a meeting, a phone call — the cache expires. When you resume, you pay full uncached input price for your entire context. For a session with 100,000 tokens of history, that’s the difference between $0.03 (cached) and $0.30 (uncached) for that one message. Multiply that across every message in the resumed session and the cost of a five-minute break can be surprisingly significant.
What else invalidates the cache? Changing your CLAUDE.md file, modifying system prompts, or altering any prefix content. The cache is prefix-matched — any change to the beginning of your prompt invalidates the cache for everything after it. This means: keep your CLAUDE.md stable mid-session. If you’re tweaking it while working, you’re breaking your cache on every edit. Make your CLAUDE.md changes between sessions, not during them.
Lever 5: Architectural Choices
This lever is about how you structure your agent configuration — what loads when, what runs where, what sees what. It’s less about individual commands and more about the shape of your setup.
Skills vs CLAUDE.md. Your CLAUDE.md loads at session start and stays in context for the entire session. Skills load only when invoked. If you have 500 lines of instructions in CLAUDE.md, that’s 500 lines of tokens in every single request. Move everything that isn’t needed on every turn into skills instead. The Anthropic guidance is to keep CLAUDE.md under 200 lines. Everything else should be a skill that loads on demand.
Subagents as context isolation. When a subagent runs, it gets its own context window. Its file reads, its verbose output, its exploration — none of that bloats your main context. Only a summary returns to you. If you need to read a large codebase, spawn a subagent to explore it rather than reading files into your main session. The subagent might read 50 files. You get a paragraph summary. That’s a massive context saving.
MCP tool overhead. MCP tools are deferred by default — only their names enter context, with full schemas loading when actually used. But every active MCP server still contributes some context overhead. Use /mcp to list your configured servers and disable any you’re not actively using. And consider whether a CLI tool (gh, aws, sentry-cli) would be more context-efficient than an MCP server — CLI tools have zero per-tool listing cost.
Hooks as pre-filters. A PreToolUse hook on the Bash tool can grep for specific errors in a log file instead of letting Claude cat the entire thing into context. A PreToolUse hook on the Read tool can block reads of files over 1,000 lines and suggest using a subagent instead. These are cheap interventions — often just a shell script — that prevent expensive context pollution.
This lever is a preview. Part 3 goes deep on cost architecture — how to structure your entire agent setup for cost efficiency at scale.
Patterns — Matching the Lever to the Situation
The five levers are most useful when you know which to reach for in a given situation. Here’s the reference I keep in my head:
| Situation | What to do |
|---|---|
| Quick file edit | Sonnet + low effort |
| Deep debugging | Opus + high effort, /compact afterwards |
| Batch processing (print mode) | --max-budget-usd cap, Haiku or Sonnet, --max-turns |
| Starting a new task in same session | /clear or /compact — don’t carry dead context |
| Long pause mid-session | Cache TTL awareness — may be cheaper to start fresh |
| Reading large codebases | Subagent with Explore, not main context |
| Quick question | Haiku, low effort, --bare mode |
A few of these deserve explanation.
Deep debugging with Opus + high effort is one of the few situations where I’ll reach for the most expensive configuration. The reasoning depth matters. Opus with high effort will trace through call stacks, consider edge cases, and identify root causes that cheaper configurations miss. But the key is the /compact afterwards — once you’ve found the fix, compress that debugging context down to just the solution. Don’t carry 200,000 tokens of debugging history into your next task.
Batch processing is where --max-budget-usd earns its keep. You’re running print mode against a set of files or tasks, and you want a hard spending cap. Combine it with --max-turns to limit how many agentic loops the model can take. Haiku is often sufficient for batch tasks — it’s fast, cheap, and perfectly capable of straightforward transformations.
The long-pause situation is one most people don’t think about. If you’ve been away for more than five minutes, your cache is gone. Resuming means paying full uncached input price for your entire context. If your context is large, it might genuinely be cheaper to /clear and start a fresh session than to resume and pay the full re-cache cost. This is counterintuitive — we’re used to thinking of continuing as free and starting over as expensive. With cache TTLs, the opposite can be true.
--bare mode for quick questions strips out everything: no hooks, no skills, no plugins, no MCP servers, no CLAUDE.md. It’s the fastest startup and the smallest context. If you just want to ask “what’s the syntax for a Python list comprehension with a condition?” you don’t need your entire agent configuration loaded. --bare gives you a raw model response at minimal cost.
Building Your Dashboard
Knowing the levers is useless if you don’t have a feedback loop. Here’s the setup I recommend.
Status Line
The status line is the always-visible indicator that keeps you honest. The most practical setup uses ccusage:
{
"statusLine": {
"type": "command",
"command": "bun x ccusage statusline --cost-source both",
"padding": 0
}
}
Add this to your settings.json and you get a persistent display showing session cost, daily cost, active billing block, burn rate, and current model. It’s like having a speedometer — you stop looking at it consciously after a while, but you always know when something’s off.
Log Retention
As mentioned earlier, the default 30-day retention means you lose your historical data. Fix this immediately:
{
"logRetentionDays": 100000
}
This goes in your settings.json. The storage is negligible — JSONL logs are small. The analytical value is not.
DuckDB Queries
Once you have logs and retention, you can start asking questions. Here are the queries I run regularly:
Cost per session:
SELECT
sessionId,
SUM(usage.input_tokens) as input_tokens,
SUM(usage.output_tokens) as output_tokens,
SUM(usage.cache_read_input_tokens) as cache_reads
FROM read_json_auto('~/.claude/projects/*/*.jsonl')
WHERE type = 'assistant'
GROUP BY sessionId
ORDER BY input_tokens DESC
Model mix over time — are you using cheaper models where appropriate, or defaulting to the expensive one for everything?
Cache hit rates — what percentage of your input tokens are cache reads versus standard input? If it’s low, you’re either changing your CLAUDE.md too often, pausing too long between messages, or not maintaining session continuity.
Context utilisation — how full does your context window get before you compact? If you’re regularly hitting 80%+ before compacting, you’re paying a premium for that bloated tail end.
What to Track
If you’re going to build a dashboard, these are the metrics that actually matter:
- Cost per task type — debugging vs generation vs refactoring vs exploration. This tells you where your money goes and whether you’re using the right model for each type.
- Cache hit rate — the ratio of cache read tokens to total input tokens. Higher is better. Below 50% means you’re paying more than you should.
- Model mix — the distribution of tokens across models. If 95% of your tokens are going through Opus and you’re doing routine coding, you have a model selection problem.
- Context utilisation — average and peak context fill percentage. Chronically high context utilisation means you’re not compacting enough.
The Discipline
Here’s the uncomfortable truth about everything in this article: none of it works if you don’t do it consistently.
Setting up a status line doesn’t help if you stop looking at it. Knowing about /compact doesn’t help if you never remember to use it. Understanding effort levels doesn’t help if you leave everything on the default because switching feels like friction.
This is a practice, not a one-time setup. Like code review. Like testing. Like any professional habit that feels annoying until it becomes automatic and then feels indispensable. The first week of tracking your token spend is tedious. The second week is interesting. By the third week, you’ll catch yourself instinctively switching to Haiku for a quick question, compacting after a debugging session, and checking your context fill before starting a complex task. It becomes muscle memory.
The goal isn’t minimum spend. I want to be clear about that, because “token discipline” can sound like “use AI less.” That’s not what this is. The goal is intentional spend. Every token earning its place. Clever tokens, not slop. The developer who spends $50 a day intentionally — using Opus where it matters, Haiku where it doesn’t, compacting proactively, caching effectively — is getting dramatically more value than the developer who spends $50 a day accidentally, burning the same amount through bloated contexts, wrong models, and max effort on trivial tasks.
One produces a day of focused, high-quality AI-assisted work. The other produces the same bill and maybe half the output.
This article covered individual practice — what you can do on your own, starting today, with the tools you already have. But individual discipline only scales so far. When you have a team of ten developers, each with their own habits and configurations, individual practice isn’t enough. You need infrastructure. You need defaults. You need a system.
That’s what Part 3: Scaling the Discipline is about — how to move from individual token awareness to team-wide practice, what the architecture looks like, and how to build a culture where intentional AI spend is the norm rather than the exception.
Steve Chambers is the founder of Viewyonder, a GenAI consultancy pioneering people with AI at work. He tracks his token spend the way runners track their splits — not to go slower, but to go smarter. If you want help building token discipline into your team’s workflow, get in touch.