v1.1.0|31 tests|0 dependencies

Where your Claude Codetokens actually go

Claude Code writes a full transcript of every session to your disk, with exact per-message token usage. Nothing reads it. This does — and it tells you which of that spend you could have avoided.

/plugin marketplace add puneet-sharma-18/claude-token-screener

Reads local files only · no network calls · nothing uploaded

The finding

63% of a typical Claude Code bill is re-reading conversation history — not generating answers.

Every turn re-sends everything before it. A long session's cost grows with roughly the square of its length, and almost none of that shows up as work you asked for. Most people have never seen this split, because nothing in the toolchain surfaces it.

Where it went2026-07-04 → 2026-08-09
  • Cache read$2,847.6163%

    6.02B tok · history re-sent each turn

  • Cache write$957.8421%

    100.03M tok · new context stored

  • Output$728.3716%

    30.14M tok · what Claude wrote

  • Input$3.040%

    656.9k tok · uncached prompt

Analyzed

6.15B

tokens across 129 sessions in 37 days

Priced at published API rates

$4,536.86

~$122.62/day

Flagged as avoidable

$1,451.80

32% of spend, across 6 findings

Real output from the author's own machine, run through --redact. Estimates from published rates, not an invoice.

Generated from 158 transcripts of the author's own usage and run through --redact, which strips every prompt, file path, and project name. Numbers and findings survive; nothing else does.

token-screener — terminal report

What it reports

Five views of the same data, plus the findings that come out of it.

Where it went

Input, output, cache-write and cache-read, priced separately and shown as a share of spend. Cache writes are split by 5-minute and 1-hour TTL so the 1.25x and 2x rates are applied correctly.

Accounting

By task

Every turn grouped under the prompt that started it, so cost maps to work rather than to messages. The script asserts per-task tokens sum to the total and warns loudly if they ever drift.

Attribution

By tool

How much context each tool's results added to the conversation. This is the section that answers what is actually filling your context window.

Attribution

By model and effort

Spend broken out per model and per reasoning-effort tier, plus main thread versus subagents — the split that tells you whether delegation is working.

Slices

Where to optimize

Ranked findings, each with the evidence behind it and an estimated saving. Seven detectors, priced by when content entered the session rather than by raw size.

Findings

However you want it

A terminal report by default, a self-contained HTML dashboard with --html, or JSON with --json. Add --redact to any of them to make the result safe to share.

Output

The seven detectors

Full catalogue ↗

Every finding the screener emits comes from one of these. Each says what it looks for, why it costs money, and what to actually do about it.

01 Long sessions re-reading their own history

Session length
Looks for
A session past ~25 turns where cache reads are over 70% of its cost.
Why it costs
Total cost grows with roughly the square of session length — each turn re-sends everything before it. A 700-turn session can spend more re-reading itself than on all its actual output combined.
Fix
/clear between unrelated tasks. /compact when one thread genuinely needs to continue. Both reset the quadratic. The instinct to keep one long session going so Claude remembers is the single most expensive habit in Claude Code.

02 Redundant file re-reads

Duplication
Looks for
The same file_path read two or more times in one session.
Why it costs
The first read already put the file in context permanently. The second adds a second copy, and both are re-sent on every later turn.
Fix
If the file changed, re-reading is legitimate. If it was re-read because it scrolled out of attention, the cost was avoidable. Frequent re-reads are also a signal the file belongs in CLAUDE.md instead.

03 Oversized tool results

Tool output
Looks for
Any single tool result over 50,000 characters.
Why it costs
One 200k-character file read is ~50k tokens sitting in context for the rest of the session. At turn 10 of a 60-turn session, that one read costs more than most tasks.
Fix
Bound output where it is produced: Read with limit/offset, Bash piped through head/tail/grep, build logs redirected to a file you then grep. For anything exploratory, delegate to a subagent so only the conclusion lands in the main thread.

04 Prompt-cache churn

Cache
Looks for
A session writing more to cache than it reads back.
Why it costs
Cache writes are 1.25–2x the input rate and only pay off when re-read. Writing without reading means paying the premium for nothing.
Fix
Usually many short sessions rather than one flowing one, so no prefix survives long enough to be reused. It can also mean something near the front of the prompt changes every turn, invalidating everything after it. If the work is genuinely one-shot questions, this is fine and can be ignored.

05 Research that should have been a subagent

Delegation
Looks for
A task that read 6+ files and edited none.
Why it costs
Every file read in the main thread stays in the main thread's context permanently, at the compounding rate — even though the answer you needed was one paragraph.
Fix
Delegate investigation. A subagent reads whatever it needs in its own context, that context is discarded when it finishes, and only the findings come back. The saving scales with how long the main session continues afterwards.

06 Top-tier model or effort on small work

Model choice
Looks for
Short, few-turn tasks with tiny output running on an expensive model or at xhigh/max effort.
Why it costs
Opus is 5x Sonnet on input and Fable is 10x. Effort drives how much thinking happens before the answer.
Fix
Drop effort first — it is the bigger lever and does not change model quality, only depth. Then consider a smaller model for that class of task. Session boot messages and one-line acknowledgements are excluded, since their cost is an unavoidable first-turn cache write.

07 Searching in the main thread

Delegation
Looks for
8+ Grep/Glob/Bash calls in the main thread on one session.
Why it costs
Search output is the highest-volume, lowest-reuse content in a session. You need it for one turn; you pay for it for every remaining turn.
Fix
Fan the sweep out to a subagent and keep only what it found. Same fix as #5 from a different angle — together they are usually the largest single lever available.

Habits that follow from all of this

  1. 01/clear between unrelated tasks. Not optional at scale.
  2. 02Delegate noisy reading and searching. Keep conclusions, not transcripts.
  3. 03Bound tool output at the source rather than after the fact.
  4. 04Tune effort before tuning model.
  5. 05Put durable project facts in CLAUDE.md so they are cached once rather than re-discovered every session.

Why context compounds

Context is not paid for once. It is paid on write, then again on every subsequent turn as a cache read.

A token entering the conversation when N more turns will follow costs roughly:

(1.25 + N × 0.10) × input_rate

This is why just read the file and just run the whole test suite are not free — and why the screener prices content by when it entered a session rather than by how big it was.

Worked example — Opus, $5/MTok input

Token added at turn 5 of 50$28.75/MTok

45 turns still to come, each one re-reading it

Token added at turn 49 of 50$6.25/MTok

one turn left to pay for

Same token. Same file. Nearly six times the cost, decided entirely by when it entered the conversation.

Install it

Python 3.9+, standard library only, no dependencies and no install step. Then ask Claude “how many tokens am I using?” or run /token-screener.

/plugin marketplace add puneet-sharma-18/claude-token-screener
/plugin install token-screener

Recommended. Adds the /token-screener command and lets Claude reach for it on its own.

Command-line flags

FlagEffect
--project PATHA specific project (default: current directory)
--all-projectsEvery project
--days NLook back N days (default 30)
--since / --untilExplicit YYYY-MM-DD range
--session IDOne session (id prefix is fine)
--top NRows per section (default 10)
--html FILEAlso write a self-contained dashboard
--jsonJSON instead of a report
--inr-rateUSD→INR for the secondary currency (default 88)
--redactStrip prompt text and file paths — makes a report safe to share

On privacy

Your transcripts are the most sensitive thing on your machine. The tool is built so that using it never puts them at risk.

No network, at all

The script imports nothing beyond the Python standard library and makes no subprocess calls. No telemetry, no uploads, nothing phoning home. You can read the whole thing in one sitting.

Read-only

It streams your transcripts and never modifies them, or any Claude Code configuration. Running it cannot change the thing it is measuring.

Local files only

Everything it needs is already on your disk in ~/.claude/projects/. The analysis happens on your machine and the report stays there unless you move it.

Before you share a report

By default, task labels are your own prompts and some findings cite absolute file paths. That is fine on your own screen and not safe to paste into an issue or a screenshot. Add --redact to anything that leaves your machine: it replaces every prompt with task 001, every path with [path], and the project name with [redacted], leaving the numbers and findings intact.

The report embedded on this page was produced exactly that way.

Safe to share
python3 screen.py --redact --html safe.html

Honest limits

What this tool does not know, stated plainly.

Costs are estimates, not an invoice
Priced from published API rates. On a Max or Pro subscription nothing is metered per token — the numbers show relative weight, not a bill.
Tool-result counts are approximated
Estimated from bytes at roughly 4 characters per token, and labelled as an estimate everywhere they appear.
Savings estimates are directional
They rank which lever is biggest. They are not refunds, and they are not what you would have paid.
Pricing is a static table
With an as_of date printed in every report. When rates change, pricing.json needs updating — the report will tell you how stale it is.

Where the tool is exact: totals match an independent sum of the raw transcripts, and the accounting invariants are locked by 31 tests running on Python 3.9, 3.11 and 3.13. 305 transcripts and 420MB analyze in about 2.4 seconds at ~140MB peak memory.