Disclosure: I build TokenBar, a Mac menu bar app that tracks AI usage and cost. It gets one mention near the end. The rest uses only Claude Code's own files and Anthropic's published prices.
"Should I upgrade to Max?" is usually answered by gut feel: you hit a limit twice in one week and start shopping. A better answer is already on your disk. Claude Code keeps a transcript of every session, and every model response in it records its token counts. Price those tokens at API rates and you get a real number to set beside each plan.
What you're choosing between
From Anthropic's pricing page and the Max plan help article, as of October 2026:
| Option | Price | Usage |
|---|---|---|
| Pro | $20/mo, or $17/mo billed yearly ($200 up front) | At least 5x Free per 5-hour session |
| Max 5x | $100/mo, monthly only | 5x Pro per session, plus $100/mo in API credits |
| Max 20x | $200/mo, monthly only | 20x Pro per session, plus $200/mo in API credits |
| API (Console) | Pay per token | No plan limits, only rate limits |
Some details matter more than the price:
- Limits aren't in dollars. Every plan has a rolling 5-hour session window, and paid plans add a weekly limit. Anthropic says there's no fixed message count, because usage depends on context length, model and features.
- It's one shared pool. Claude Code, claude.ai, desktop and mobile all draw from the same allowance.
- When you hit a limit, you can wait, upgrade, or turn on usage credits and keep going at standard API rates.
The API prices you'll use
Per million tokens, from the API pricing docs:
| Model | Input | 5-min cache write | 1-hour cache write | Cache read | Output |
|---|---|---|---|---|---|
| Opus 5.5 | $4 | $5 | $8 | $0.20 | $20 |
| Sonnet 5.5 | $2 | $2.50 | $4 | $0.10 | $10 |
| Haiku 5.5 (prompts up to 100k) | $0.10 | $0.125 | $0.20 | $0.01 | $0.50 |
| Haiku 5.5 (prompts over 100k) | $0.50 | $0.625 | $1 | $0.05 | $2.50 |
Cache reads are where most Claude Code tokens land. A long session re-sends its whole history on every request, and caching is the reason that's affordable. One detail affects the comparison: per the Claude Code cost docs, the cache lifetime is an hour on a subscription but five minutes by default on an API key. So the same work can cost a bit more on the API, because you rebuild the cache more often after short breaks.
Where the numbers live
Claude Code writes transcripts as JSONL to ~/.claude/projects/<project-dir>/<session-id>.jsonl, and keeps them for 30 days by default (cleanupPeriodDays). Assistant lines carry a message.usage object:
"usage": {
"input_tokens": 5,
"cache_creation_input_tokens": 20780,
"cache_read_input_tokens": 15718,
"output_tokens": 1101
}
Two caveats before you trust a script:
-
Anthropic calls the format internal, so it can change in any release. For anything long-lived, the sessions docs point you to
claude -p --output-format json, which returns usage and cost for a run, or to/export. -
One response can span several lines. Claude Code may write one line per content block, each repeating the same
message.idand usage. If you sum every line you'll overcount, so dedupe bymessage.id.
A small script to price your last 30 days
#!/usr/bin/env python3
# claude_cost.py: API-equivalent cost of local Claude Code sessions
import json, pathlib, collections
# $ per million tokens: input, 5m write, 1h write, cache read, output
PRICES = {
"opus": (4.00, 5.00, 8.00, 0.20, 20.00),
"sonnet": (2.00, 2.50, 4.00, 0.10, 10.00),
"haiku": (0.10, 0.125, 0.20, 0.01, 0.50), # prompts <= 100k
}
HAIKU_LONG = (0.50, 0.625, 1.00, 0.05, 2.50) # prompts > 100k
msgs = {}
for f in pathlib.Path.home().glob(".claude/projects/**/*.jsonl"):
for line in f.open(errors="ignore"):
try:
e = json.loads(line)
except ValueError:
continue
m = e.get("message") or {}
if e.get("type") != "assistant" or "usage" not in m:
continue
key = m.get("id") or e.get("uuid")
prev = msgs.get(key)
if not prev or m["usage"].get("output_tokens", 0) >= prev[2].get("output_tokens", 0):
msgs[key] = (e.get("timestamp", "")[:10], m.get("model", ""), m["usage"])
days = collections.defaultdict(float)
for day, model, u in msgs.values():
fam = next((k for k in PRICES if k in model), None)
if not fam:
continue # unknown or synthetic model entries
inp, cr = u.get("input_tokens", 0), u.get("cache_read_input_tokens", 0)
cw = u.get("cache_creation_input_tokens", 0)
split = u.get("cache_creation") or {}
w1h = split.get("ephemeral_1h_input_tokens", 0)
w5m = cw - w1h
p = PRICES[fam]
if fam == "haiku" and inp + cr + cw > 100_000:
p = HAIKU_LONG
days[day] += (inp*p[0] + w5m*p[1] + w1h*p[2] + cr*p[3]
+ u.get("output_tokens", 0)*p[4]) / 1e6
for d in sorted(days):
print(f"{d} ${days[d]:8.2f}")
active = [v for v in days.values() if v > 0]
print(f"\nActive days: {len(active)} Total: ${sum(active):.2f} "
f"Avg per active day: ${sum(active)/max(len(active),1):.2f}")
Run it with python3 claude_cost.py. It maps models by family name, so check the table against the pricing page whenever Anthropic changes prices. Older model versions are priced differently. Opus 4.8, for example, is $5 in and $25 out.
The ** glob also picks up subagent transcripts if your version writes them to subfolders. You want those included, because subagent requests count toward your usage too.
Reading the result
Treat the number as "what this would have cost on the API," not "how much of my plan I used." Anthropic doesn't publish a dollar equivalent for plan allowances, so no exact break-even point exists. These are the comparisons that do hold up:
- Monthly API-equivalent below $20. Pay-as-you-go in the Console may cost you less than Pro. You lose claude.ai chat, and the cache expires sooner, but if you mostly use Claude Code a few days a month, it's worth a look.
- Well above $20, but you rarely see a limit message. Pro is doing its job. Upgrading buys headroom you don't use.
-
You hit the 5-hour or weekly limit every week. Open
/usage. On paid plans it shows your plan bars and a breakdown by skills, subagents, plugins and MCP servers, and it flags any behavior (long context, cache misses) that makes up 10% or more of your usage. Pressdorwto switch between the last day and week. Fix what it flags first. If you still hit the wall, Max 5x is the next step. - You're comparing Max with the API. Max includes $100 or $200 a month in API credits on top of your plan usage, so count those if you'd use them.
For a reference point, Anthropic's cost docs say enterprise Claude Code deployments average about $13 per developer per active day and $150–250 per developer per month, with 90% of users under $30 per active day. Those are API-rate figures for heavy, full-time use. If your average per active day is close to that, you're a normal heavy user, not an outlier.
Use the right /usage number
The Session block at the top of /usage shows a dollar cost calculated locally at list price. Anthropic says it's meant for API users. On Pro or Max it doesn't affect your bill, and it resets on /clear. It's still useful as a per-task price tag. Run /clear, do one task, then check /usage, and you'll know what that kind of task costs.
Check again after a month
One month of data beats any blog post's rule of thumb, mine included. Run the script at the end of each month (transcripts expire after 30 days unless you change cleanupPeriodDays), and compare it with how often you hit a limit.
I wanted that number visible without running a script, so I built TokenBar, which shows Claude, Codex and other providers' usage and cost in the Mac menu bar. The script above gives you the same core number for free.
What does your average active day come out to? I'm curious how far apart people's numbers are.
Top comments (0)