Optimizing Claude Code token usage: lessons learned

After a few weeks of heavy Claude Code usage, the bill climbs. Not because tasks are more complex — because sessions get bloated. Claude loads all available context, re-reads the same files every exchange, and CLAUDE.md grows longer with each new rule added. Result: you're paying for useless context, not for actual work.

Here are the levers that had the most impact on my project — a PHP portfolio with an automated news monitoring system in Node.js. No magic recipes, just concrete adjustments with real effects.

.claudeignore: what Claude should never read

By default, Claude Code can index any file in the working directory. On my project that included uploads/ (hundreds of runtime JSON files), .playwright-mcp/, temporary session plans, and all binary assets. None of these files are useful when debugging a Node.js script.

The solution is a .claudeignore at the root, using the same syntax as .gitignore:

# Runtime data — useless for coding
uploads/
scripts/.retro-state.json
scripts/.veille.lock

# Playwright
.playwright-mcp/

# Generated plans/specs
docs/superpowers/

# Binary assets
assets/images/
assets/plugins/

# Blog comments
blog/comments/

The effect is immediate: Claude no longer loads these files during automatic project exploration. On my uploads/ folder exceeding 2 MB of JSON, this is the most significant gain.

Split CLAUDE.md by domain

CLAUDE.md is injected into every session. If it's 300 lines long, they're all there from the first exchange — even when working on blog CSS with no reason to know the subtleties of the monitoring daemon.

Claude Code supports the @path syntax to import other files. But the import is automatic — it always loads the referenced file. That's not conditional loading.

The real solution: split the files and don't import them automatically. I split my CLAUDE.md in two:

  • CLAUDE.md — stack, deployment, LinkedIn bot. 24 lines.
  • CLAUDE.veille.md — the entire monitoring system. Loaded manually when needed.

In CLAUDE.md, just a note:

> Monitoring system: see `CLAUDE.veille.md`

When I work on the monitoring system, I explicitly tell Claude "read CLAUDE.veille.md". The rest of the time, the file doesn't exist in context. The main CLAUDE.md went from 260 to 24 lines.

/clear between each distinct task

This is the most underrated lever. A Claude Code session accumulates everything: files read, previous exchanges, failed attempts. If you chain "add a field to the form" → "fix this daemon bug" → "write this article", the session context contains all of that simultaneously.

Each exchange is billed against the entire accumulated context. A 2-hour session can cost 3x more than a series of short sessions doing the same work.

Practical rule: /clear as soon as you switch tasks. /compact if you want to keep a summary of what was done before continuing on the same topic.

Targeted questions, not explorations

"How does the monitoring system work?" — Claude will read 8 files, retrace the architecture, and produce a 500-token explanation. If you just wanted to know how deduplication works, you paid for a lot of useless context.

The efficient version: "in scripts/run-veille.js, how does SHA256 dedup work?" Claude reads one file, goes directly to the function, answers in 50 tokens.

Same logic for modifications. Rather than "I want to modify the FTP loop behavior", give the file and line: "in scripts/run-veille.js line 180, I want the condition to also ignore .html files". Claude makes a minimal diff without re-reading the entire file.

Haiku for simple tasks — with caveats

Claude Haiku costs about 20x less than Sonnet at equivalent volume. For mechanical tasks — variable renaming, adding a case to a switch, fixing a typo in a comment — it gets the job done.

But the cost of back-and-forth often cancels out the gain. On a project with implicit coupling (JSON registry driving a daemon that syncs via FTP), Haiku will regularly miss a constraint and propose a superficial fix. You then spend 3 exchanges correcting what one Sonnet exchange would have resolved.

Good usage: /model haiku for factual questions ("where is function X defined?", "what's the schema of this JSON?") and single-line changes in isolated context. Stay on Sonnet as soon as the task involves multiple files or non-trivial business logic.

Open Claude from a subdirectory

Claude Code indexes the directory it's launched from. Launch from the project root and everything is available. Launch from veille/ and only that folder is in the auto-exploration scope.

For focused work on a single module — monitoring admin, Node.js scripts, blog — opening Claude from the right subdirectory mechanically reduces what it can inadvertently load.

Conclusion

None of these optimizations is spectacular in isolation. The effect comes from their combination: a short CLAUDE.md, a .claudeignore that excludes runtime data, short and focused sessions, precise questions with file and line number.

What remains most counterintuitive: long sessions seem productive because you get a lot done. In practice, a 20-minute session with /clear between each task costs less and produces work as clean as a 2-hour uninterrupted session — often better, because Claude doesn't have to manage a context that has become incoherent.

Comments (0)