Claude Code spend tracker: which one dey work?
Claude Code spend trackers no dey answer the same question. Compare local log parsers, Anthropic usage screens and OpenTelemetry for honest spend figures.
Wetin Claude Code spend tracker dey actually read
Every Claude Code spend tracker dey read one of three data sources, and na the source dey decide which question e fit answer. Log parser dey read session transcript files wey dey your own disk. Dashboard dey read usage records wey Anthropic dey keep for your account or organisation. Metrics backend dey read OpenTelemetry (OTel) stream wey Claude Code dey emit when you switch am on. All three fit dey correct for the same time and still no agree, because dem dey count different things.
This guide no dey explain tokens again. how Claude Code dey count token usage cover input, output, cache writes and cache reads, and dashboard no go mean much until that part clear. The question here narrow: for each type of tool, wetin e fit see, and wetin e no fit ever see.
Why three Claude Code spend trackers appeared on one day
Same day, dem post three different Claude Code spend trackers. Dem no be three versions of the same tool, and na that one make the matter useful. One parse the local session files. One wrap the account usage screens. One na hosted tracing backend wey you run by yourself.
Dem show up together because the cost of agent session no dey obvious again. Chat cost roughly wetin you fit see for screen. Agent fit read twenty files, run the test suite, and send the whole conversation again for every turn. So, context wey you never type na wetin dey drive the bill. For subscription, no dollar figure dey at all. Na only usage bar dey show, and e dey empty faster on some days pass others. Each of the three tools dey fill different part of this gap.
Shape 1: local log parser dey tell you wetin today cost
Claude Code dey store each conversation as JSON Lines (JSONL) for ~/.claude/projects/<project>/<session-id>.jsonl, where <project> na your working directory path wey replace non-alphanumeric characters with -. Every assistant turn for that file get token counts for its request. Log parser go add dem together and calculate the price.
ccusage na the one wey most people dey use. E no need installation:
npx ccusage@latest daily
npx ccusage@latest daily --breakdown
npx ccusage@latest blocks
npx ccusage@latest session --jsondaily dey total by date. --breakdown dey split each row by model, na so you fit find out say one Opus afternoon use most of the week. blocks dey group by the five-hour window wey subscription reset on. session dey total per conversation, and --instances dey group by project so you fit see which repository cost pass. Add --since and --until to limit the range, and run npx ccusage@latest daily --help for the date format wey your version expect. As of August 2026, e still fit read other agent CLIs, including Codex and OpenCode. This matter if you dey compare dem.
Model price table dey provide the pricing, and the tool get three cost modes. --mode auto dey use the costUSD value wey Claude Code write inside the file when e dey there, and e calculate from token counts when e no dey. --mode calculate dey always calculate from tokens and ignore any recorded cost. --mode display dey show only recorded costs and print $0.00 for rows wey no get any. If total look wrong, run the same report under calculate, then run am under display. Big difference between dem mean say most entries no get recorded cost, so everything wey you dey read na estimate.
You fit use the same data for your prompt. ccusage statusline dey print one short line for Claude Code status bar, and you fit connect am to ~/.claude/settings.json like any other status line command. See how to build Claude Code statusline for the settings block and the fields wey e dey receive.
Wetin log parser no fit see na anything wey no happen for this machine. Another laptop, session for claude.ai, or work wey teammate do: those transcripts dey for those disks. Old data fit still dey missing, because cleanupPeriodDays setting dey clean up transcripts after 30 days by default. So last quarter don disappear unless you archive am.
One more risk dey, and e concern the structure. Anthropic documentation talk say entry format na internal to Claude Code and e fit change between versions. So scripts wey parse these files directly fit break for any release. This apply to every tool wey work like this. Na also why hand-written jq one-liner over the JSONL no good as e look: maintained parsers dey track format changes for you, but your one-liner go report wrong number with confidence the day dem rename one field.
Finally, dollar figure need one warning when na subscription. You no dey pay per token for Pro or Max, so the number na wetin your tokens for cost at list API rates. E measure how heavy your usage be. E no be your bill. If the real question na which plan you suppose use, that comparison na separate work: see API billing compared with Claude subscription.
Shape 2: usage screen wey dey inside go tell you which model chop the budget
Claude Code get im own reporting, but plenty people no dey ever open am. Run /usage inside session. The Session block for top go show tokens by model and dollar amount for current session. E dey calculate am locally from token counts with standard list rates. That amount no include discount or promotional pricing, so e fit different from your invoice. The totals go reset when /clear start new conversation.
For Pro, Max, Team or Enterprise plan, the same screen go show how much of your plan limit you don use. E go also assign recent usage to skills, subagents, plugins and individual MCP servers as percentage of the total. E go flag behaviours wey account for 10% or more of recent usage, like long context or cache misses. Press d or w to switch between the last 24 hours and the last 7 days. These figures na approximate values wey local session history for this machine calculate, so usage from second device no dey count. When that bar empty instead of just low, the screen go tell you say the window don close, but e no go tell you how to continue work. Wetin to do after you don reach the limit na separate decision about model, context and plan.
When developers pass one person, the numbers move go the account. API organisation go get Console usage page, Claude Code dashboard wey show spend and accepted lines for each member, and Claude Code Analytics API wey return the same daily per-user metrics with admin key. Teams and Enterprise plans get spend report for admin console with CSV export. E dey update daily, and Enterprise add analytics API. Which one you go see depend on how each developer sign in, so mixed organisation fit need read two reports and add the totals by hand.
To size budget, the published figure for Anthropic cost documentation as of August 2026 na average close to $13 per developer per active day and $150 to $250 per developer per month, with 90% of users below $30 per active day. Treat am as published benchmark from enterprise deployments, no be prediction for your team. Run pilot group and measure first before you extrapolate.
The dashboards no fit see anything below day and person level. Dem go tell you say Opus use most of Tuesday. Dem no go tell you which prompt, repository or CI job cause am. Dem also dey lag because organisation reports dey update daily, so dem na review tool, not tool to catch runaway agent this afternoon. To catch runaway agent, you need limits, not reports. Na that how to keep agent costs bounded on a VPS dey discuss.
Shape 3: your own OpenTelemetry stack go tell you which prompt cause regression
Claude Code dey emit OpenTelemetry metrics and events once you set one environment variable, and na only this option dey stream per-user token and cost data enter system wey you control almost real time. The metrics include claude_code.cost.usage for USD, claude_code.token.usage for tokens, claude_code.session.count and claude_code.active_time.total.
The token metric na the interesting one because of its attributes. Each data point carry type, wey be input, output, cacheRead or cacheCreation, plus model and query_source, wey be main, subagent or auxiliary. E also carry agent.name, skill.name, mcp_server.name and mcp_tool.name. This don reach to answer questions wey no dashboard fit answer: how much of the bill come from subagents instead of your own turns, whether one MCP server double your input tokens, and whether cache reads drop after person edit CLAUDE.md. Cache behaviour na usually where surprise dey hide, and when prompt caching pays for itself explain wetin you dey look at.
Make we correct one thing because e dey come up for every thread about this. Langfuse na good self-hosted tracing backend, and self-hosting Langfuse for agent tracing cover how to run am for VPS. Its OTLP endpoint accept traces only. Claude Code dey export metrics and log events, no spans, so if you point OTEL_EXPORTER_OTLP_ENDPOINT to Langfuse, the project go remain empty and you no go get any useful error. Langfuse na the correct tool for agents wey you build directly with the API, where your own code create each span with its prompt, model and cost. For Claude Code CLI, metrics store na the right match.
Set up Claude Code spend tracking for your own VPS
Services two dey enough: one collector to receive the metrics, and Prometheus to store dem. Keep both away from public internet, because open OTLP port go accept writes from anybody wey find am. Write /opt/ccmetrics/compose.yaml:
services:
collector:
image: otel/opentelemetry-collector-contrib:latest
command: ["--config=/etc/otel/config.yaml"]
volumes:
- ./collector.yaml:/etc/otel/config.yaml:ro
ports:
- "10.8.0.1:4318:4318"
restart: unless-stopped
prometheus:
image: prom/prometheus:latest
volumes:
- ./prometheus.yml:/etc/prometheus/prometheus.yml:ro
- prom-data:/prometheus
ports:
- "127.0.0.1:9090:9090"
restart: unless-stopped
volumes:
prom-data:10.8.0.1 na the server address inside WireGuard tunnel, so your machines fit reach the collector, and nobody else fit reach am. The address before the port dey do real work here, because published Docker ports no dey follow ufw filtering: see why Docker published ports bypass ufw. To set up the tunnel itself, see a WireGuard VPN for your own VPS.
/opt/ccmetrics/collector.yaml:
receivers:
otlp:
protocols:
http:
endpoint: 0.0.0.0:4318
processors:
batch:
exporters:
prometheus:
endpoint: 0.0.0.0:8889
service:
pipelines:
metrics:
receivers: [otlp]
processors: [batch]
exporters: [prometheus]/opt/ccmetrics/prometheus.yml. Port 8889 no dey publish to the host, because Prometheus dey reach the collector through the Compose network by service name:
global:
scrape_interval: 30s
scrape_configs:
- job_name: claude-code
static_configs:
- targets: ["collector:8889"]cd /opt/ccmetrics
docker compose up -d
docker compose logs collectorCollector log suppose end with Everything is ready. Begin running and processing data.. If log stop because of config error, e mean say YAML no parse, and the container go restart repeatedly.
Now point Claude Code to am. For every machine wey dey run Claude Code, add this to ~/.claude/settings.json:
{
"env": {
"CLAUDE_CODE_ENABLE_TELEMETRY": "1",
"OTEL_METRICS_EXPORTER": "otlp",
"OTEL_LOGS_EXPORTER": "none",
"OTEL_EXPORTER_OTLP_PROTOCOL": "http/protobuf",
"OTEL_EXPORTER_OTLP_ENDPOINT": "http://10.8.0.1:4318",
"OTEL_METRIC_EXPORT_INTERVAL": "10000"
}
}Start one session, send one prompt, wait for the export interval (10 seconds here, 60 seconds by default), then ask Prometheus wetin e don learn:
curl -s http://localhost:9090/api/v1/label/__name__/values | grep -o 'claude_code[a-z_]*'You suppose see several names wey start with claude_code_. The exporter dey change the dots to underscores and add the unit, so the exact strings depend on your collector version. Empty result mean say nothing don arrive. Check say the protocol and port match, because http/protobuf dey go 4318 and grpc dey go 4317, and mismatch fit fail quietly. Run claude --debug and the debug log go report OTel export errors.
If na one machine and you no need server, skip everything above. Set OTEL_METRICS_EXPORTER=prometheus and Claude Code go expose scrape endpoint for http://localhost:9464/metrics itself. When prometheus na the only exporter wey you list, Claude Code no go put USD, tokens and s units for the metric names, so the scrape go remain valid Prometheus text format.
This setup get one privacy decision. By default, na counts only dey leave the machine; prompt text and tool output no dey leave. OTEL_LOG_USER_PROMPTS=1 and OTEL_LOG_TOOL_CONTENT=1 go change this, and then your metrics box go contain source code plus anything else wey dey inside context. Turn dem on deliberately, and first read how to keep secrets out of agent context.
Track spending for scripted and CI runs
Non-interactive runs na dem dey surprise people, because nobody dey watch the screen. claude -p together with --output-format json reports the cost of that run inside its result payload:
claude -p "summarise the failing tests" --output-format json | jq '.total_cost_usd'The payload carry total_cost_usd plus breakdown for each model, so CI job fit record its own spending without any dashboard. Append the value to a file, or push am as metric go the collector above. Na the cheapest useful way to track spending, and e cost one jq call for each run.
Failure mode dem and wetin you go see
The report empty. npx ccusage@latest daily no print any row because e no dey read the place wey Claude Code dey write. CLAUDE_CONFIG_DIR dey move that location, so parser need make you tell am about the new location. If rows dey but dem stop around one month ago, na cleanupPeriodDays dey work as e suppose: by default, transcripts dey remove after 30 days.
Two machines report different totals. Na expected behaviour, e no be bug. Both /usage and any log parser dey read local session history only, so usage from another device or from claude.ai no dey inside either one.
The local total no match the invoice. Local figures dey come from token counts wey use standard list rates. Dem no know anything about promotional pricing or contracted discount. For subscription, dem no dey bill your tokens one by one at all. Console usage page na the authoritative source for API billing.
Cost increase even though you do the same work. Check the cache columns first. Long session dey resend the complete history for every turn. E dey use cached rate while cache still warm, but once cache go cold, e go use full input rate. This mean one long break fit make am process the whole conversation again. You go see large input number beside small output number. input against output token pricing explain why both figures fit move independently.
A day wey get subagents look impossible. Every subagent dey run im own context window. So token use dey depend on how many run and how long each one last. Na only OTel data fit separate dem, through the query_source attribute for claude_code.token.usage. Log parser go show you the total, and leave you to guess.
FAQ
ccusage dey show wetin dem really bill me for Max plan?
No. For subscription, dem no dey bill you per token. So log parser dey price your tokens with standard list API rates and show wetin the same work for don cost through the API. E good as relative measure of how heavy one day be. E also useful to compare projects or models with each other. For wetin you owe, Console usage page cover API billing, while plan billing page cover subscription billing.
Where Claude Code dey store the session files wey these tools dey read?
For ~/.claude/projects/<project>/<session-id>.jsonl. For there, <project> na working directory path wey replace non-alphanumeric characters with -. Each line na one JSON object for one message, tool use, or metadata entry. CLAUDE_CONFIG_DIR dey move the whole directory. cleanupPeriodDays inside settings.json dey control the 30-day retention. Anthropic document the entry format as internal and e fit change between versions. So use maintained tool to parse am instead of your own script.
I fit send Claude Code telemetry go Langfuse?
No be directly. Langfuse OTLP endpoint dey accept traces. Claude Code dey export metrics and log events instead of spans, so the data no get where e go land. Send Claude Code metrics go OpenTelemetry collector and store dem for Prometheus. Use Langfuse for agents wey you build yourself on the API, where your own code dey emit spans wey carry the prompt, the model, and the cost.
Why my local numbers no match Console usage page?
Because dem calculate dem differently. /usage and log parsers dey add token counts from session files for the machine wey you dey use, then price dem with standard list rates. Console dey report wetin your organisation actually pay, across every machine and every key, after any discount. Mismatch dey normal. If the difference big well well, e usually mean say another device, CI runner, or another team member dey bill to the same account.
How I fit track the cost of claude -p run for CI?
Run am with --output-format json and read total_cost_usd from the result, for example with claude -p "..." --output-format json | jq '.total_cost_usd'. The same payload dey include per-model breakdown and the session ID. Record that value for each job, and you get per-pipeline spend without agent, dashboard, or extra service.