Most people optimising their AI coding costs start in the wrong place. They shorten their prompts, or switch to a cheaper model for everything, or start new sessions constantly to "keep the context small". Then the bill barely moves.
The reason is that most AI coding cost is input, not output. The whole transcript, plus every file the harness auto-loads, is re-sent on every single turn. You are not paying for the answer. You are paying, over and over, for everything the model has to read before it can give you one.
Once that clicks, the whole problem reduces to a single distinction.
Eager context vs lazy context
Eager context is loaded every turn: CLAUDE.md and anything the harness auto-loads, such as .claude/rules/*. You pay for it on every message, whether or not it was relevant to what you just asked. Keep it lean.
Lazy context is loaded only when it is actually used: skills, where only the ~150-token description is eager and the body loads on invocation, and subagents, whose file reads stay inside the subagent and never enter your main thread. Put the bulk and the detail here.
That gives you the core move: rules become tight checklists, and examples and templates move into skills. Nothing is deleted. It just stops being re-read on every turn.
Two more multipliers stack on top. Model tiering — a cheaper model for routine mechanical work, the top model for architecture and judgment. And prompt-cache hygiene — long, stable sessions, and avoid clearing mid-task, because clearing throws away the cached prefix you already paid to build.
The two bugs worth hunting first
On real projects, two problems account for most of the waste, and both are invisible until you go looking:
- Skills and commands that generate an architecture the codebase doesn't actually use. This is worse than expensive — it is wrong. The model confidently follows guidance that describes a system you migrated away from a year ago.
- Big rule files that load every turn but are 80% examples. The standards in them are worth keeping. The twelve code samples illustrating those standards are not worth re-sending on every message for the rest of the project's life.
Fixing the second one is usually a same-afternoon job with an immediate, measurable effect.
Pick the right artifact in the first place
Most of this is avoidable if you choose correctly when you create something. The rule of thumb:
- Rule — a standard that must always apply automatically. Eager, so keep it a tiny checklist of must/never/always statements. No long code.
- Skill — a repeatable procedure with steps and examples, triggered by intent. Lazy, so detail is fine. Most things belong here. One skill, one job.
- Command — a workflow you invoke explicitly, often orchestrating skills and scripts. Keep it thin; reference skills rather than inlining them.
- Subagent — an isolated worker for parallel fan-out or context isolation: search sweeps, audits, parallel edits. Lazy, and it keeps the main thread cheap.
- Hook — an automatic shell action on an event, like linting after an edit. The harness runs it, not the model, so it costs no tokens at all.
A useful habit for rule files: end them with a pointer such as "Examples and recipes: the <skill> skill" — then push every example out to that skill. The standard stays eager. The illustration goes lazy.
Make CLAUDE.md a router, not an encyclopedia
The most common failure I see is a CLAUDE.md that has grown into project documentation. It is the single most expensive file in the repo, because it is re-read on every turn forever.
What it should contain: what the project is, where things live, pointers to the sources of truth, a short "use skill or rule X when doing Y" table, the hard rules, and a token-and-cost section. What it should not contain: anything a subagent could look up on demand.
The rule that keeps this honest
Never trade quality for tokens. Leaning a file means removing examples, never standards. If you find yourself dropping a "never do X" rule because it was long, you have stopped optimising and started degrading. Every must/never/always statement should survive the process — grep for them afterwards and verify.
The companion rule: one source of truth. When two files disagree, fix the one that is wrong rather than reconciling them in the middle. Put authoritative decisions in decision records and point at them.
Doing it on an existing project
Optimising a repo that was never set up this way has one extra step that a fresh project doesn't: you have to establish ground truth first. A typical repo has no decision records — often no .claude/ at all — so there is nothing to audit against. Read the actual code, infer the real architecture and conventions, and write that down before judging a single existing file. Otherwise you are auditing documentation against other documentation.
After that it is mechanical: inventory what loads eagerly versus lazily, produce a keep/update/delete plan with reasons, restructure for cost, audit every artifact against the ground truth, then verify and commit. Commit a baseline first, and prefer archiving over hard-deleting if the git history is thin.
Claude Code: Context & Cost Optimization Playbook
The full playbook, including the two copy-paste prompts this article describes: a phased instruction for optimising an existing un-optimised project, and an authoring guide for building skills, rules, commands and agents the lean way from day one. Plus the artifact-selection table and the frontmatter templates.
What actually changes
The point of all this is not frugality for its own sake. It is that a lean setup is also a correct setup. Files that are small enough to read are small enough to keep accurate. The projects where the AI behaves strangely are almost always the projects where three files disagree about how the system works and all three are loaded on every turn.
Get the eager surface small, push the detail into things that load only when needed, and make every artifact match the real code. The cost saving is the side effect. The reliability is the point.