cheat sheet
ccusage
Local-first CLI and TypeScript library that reads JSONL session logs from Claude Code, Codex, and 13 other coding agents to produce daily/weekly/monthly/session/billing-block reports of token spend.
ccusage — Claude Code & Coding-Agent Token Usage Analyzer
What it is
ccusage is a Node.js CLI by Ryota Murakami (ryoppippi/ccusage, current version v20.0.6, May 2026) that parses the local JSONL session logs written by 15 coding agents — Claude Code, Codex, OpenCode, Amp, Droid, Codebuff, Hermes Agent, pi-agent, Goose, OpenClaw, Kilo, Kimi, Qwen, GitHub Copilot CLI, Gemini CLI — and rolls them up into daily, weekly, monthly, per-session, and per-billing-window cost reports. It runs entirely offline (no API key, no telemetry, no upload), ships as a single bunx/npx invocation with no install required, and exports the same data loaders as a typed JS/TS library when you want to embed the analysis into your own dashboard. Reach for it whenever you want to know how much you actually spent on Claude Code this week without copying anything into a spreadsheet — the closest alternative is better-ccusage (a fork with extra commands), but the upstream is more actively maintained.
Install
ccusage works best as a one-off bunx/npx invocation — no global install needed. The package's bin entry registers a ccusage executable that the package manager runners pick up automatically.
# Run without installing — Bun (recommended; cold start ~10× faster than npx)
bunx ccusage daily
# Run without installing — npm
npx ccusage@latest daily
# Run without installing — pnpm
pnpm dlx ccusage daily
# Install globally if you want `ccusage` on $PATH
npm install --global ccusage
bun add --global ccusage
pnpm add --global ccusage
# Add to a project for library use
npm install ccusage
pnpm add ccusage
bun add ccusage
# Nix (flake-based)
nix run github:ryoppippi/ccusage -- daily
Output: (none — exits 0 on success)
Syntax
Every ccusage invocation is ccusage <command> [flags]. Commands are one of the report types; flags filter, format, or change the cost-calculation mode. With no command, ccusage prints help.
ccusage <command> [--since YYYYMMDD] [--until YYYYMMDD] [--json] [--breakdown]
[--mode auto|calculate|display] [--order asc|desc]
[--offline] [--timezone TZ] [--debug] [--config FILE]
[command-specific flags]
Output: (none — exits 0 on success)
Concrete shapes:
ccusage daily # today + recent days, table view
ccusage daily --since 20260101 --until 20260131 # date range
ccusage monthly --breakdown # per-model cost breakdown
ccusage session --project myhost # filter to one project
ccusage blocks --active # current 5-hour billing window only
ccusage blocks --live --refresh-interval 10 # real-time monitoring
ccusage statusline # one-line summary for shell prompts
Output: (none — see per-command sections below)
Essential options
These flags work on every report command and are the day-to-day controls.
| Option | Short | Meaning |
|---|---|---|
--since YYYYMMDD | — | Inclusive start of the date range. Format is exactly 8 digits, no dashes. |
--until YYYYMMDD | — | Inclusive end of the date range. |
--json | -j | Emit a single JSON document instead of the formatted table — for piping to jq, dashboards, or CI checks. |
--breakdown | -b | Show per-model rows (sonnet vs. opus vs. haiku, GPT-4 vs. GPT-4o, etc.) under each aggregate. |
--mode auto|calculate|display | — | Cost source. auto (default) prefers the cost stored in the JSONL by the agent and falls back to live pricing; calculate always recomputes from token counts and ccusage's pricing table; display uses only what the agent recorded. |
--order asc|desc | — | Sort direction for rows. desc (newest/largest first) is the default. |
--offline | -O | Skip the live LiteLLM pricing fetch; use the bundled pricing table that ships with this ccusage version. |
--timezone TZ | -z | IANA timezone for date bucketing — UTC, Europe/London, Asia/Tokyo. Defaults to the system timezone or $CCUSAGE_TIMEZONE. |
--debug | — | Print pricing mismatches and which config file paths were tried. |
--debug-samples N | — | When --debug finds pricing discrepancies, show up to N sample records. |
--config FILE | — | Path to an explicit JSON config file (highest precedence after CLI flags). |
Per-command flags:
| Command | Flag | Meaning |
|---|---|---|
daily | --instances / -i | Group rows by project as well as by date. |
daily, session | --project NAME / -p | Filter to a single project (matches the directory name under ~/.claude/projects/ or the alias defined in config). |
weekly | --start-of-week monday|sunday | Which day starts the calendar week (ISO default = Monday). |
session | --id UUID | Show one specific conversation by its session UUID. |
blocks | --active / -a | Show only the currently-active 5-hour billing window. |
blocks | --recent / -r | Limit to blocks within the last 3 days. |
blocks | --token-limit N | Trigger a visual warning when projected usage exceeds N tokens for the current block. |
blocks | --live | Curses-style live view that re-renders on a timer — pair with --refresh-interval. |
blocks | --refresh-interval SEC | How often --live re-reads the JSONL files (default 5s). |
blocks | --session-length HOURS | Override the default 5-hour billing window (e.g. for testing or providers with a different window). |
statusline | --cache | Cache the result so subsequent invocations within a few seconds are instant — important when the statusline is rendered every keystroke. |
Configuration
ccusage loads settings from four sources in strict precedence — CLI flags > --config FILE > environment variables > config files (project → user → legacy user) > built-in defaults. Config files are JSON only, validated against the published schema at https://ccusage.com/config-schema.json (which gives you autocomplete in VS Code and JetBrains IDEs out of the box). Reach for a config file when you want sensible defaults like a fixed timezone, an --instances grouping, or per-command flags you'd otherwise type every invocation.
File locations — ccusage walks these at startup, top to bottom; the first match per key wins.
| OS | Path(s) | Notes |
|---|---|---|
| Linux | ./.ccusage/ccusage.json (project-local), $XDG_CONFIG_HOME/claude/ccusage.json (defaults to ~/.config/claude/ccusage.json), ~/.claude/ccusage.json (legacy) | Walks all three; per-key shallow merge — project overrides user overrides legacy. |
| macOS | Same as Linux — ccusage follows XDG, not ~/Library/Application Support | The ~/.claude directory is what Claude Code itself uses, hence the "legacy" fallback. |
| Windows | .\.ccusage\ccusage.json (project-local), %USERPROFILE%\.config\claude\ccusage.json, %USERPROFILE%\.claude\ccusage.json | No %APPDATA% support — XDG-style paths only. |
Loading precedence (highest to lowest):
- Command-line flags (
--since 20260101,--timezone UTC) --config FILEexplicitly passed on the command line- Environment variables (
CCUSAGE_TIMEZONE,CCUSAGE_OFFLINE,CLAUDE_CONFIG_DIR,CODEX_HOME, …) - Project config:
./.ccusage/ccusage.json - User config:
~/.config/claude/ccusage.json - Legacy user config:
~/.claude/ccusage.json - Built-in defaults
Options reference — top-level keys are $schema, defaults, commands, and one optional namespaced block per supported source (claude, codex, amp, opencode, …). Inside each source block you can repeat the same defaults / commands structure to override globals on a per-agent basis.
defaults — applied to every command
| Option | Type | Default | Possible values | Description |
|---|---|---|---|---|
timezone | string | system tz | IANA tz name (UTC, America/New_York, Asia/Tokyo) or local | Date-bucketing timezone for daily/weekly/monthly grouping. |
mode | enum | auto | auto | calculate | display | Cost-calculation strategy (see Essential options). |
breakdown | bool | false | true | false | Always include per-model row breakdown. |
offline | bool | false | true | false | Skip live pricing fetch. |
json | bool | false | true | false | Default to JSON output globally — useful when ccusage runs in CI. |
debug | bool | false | true | false | Print pricing-mismatch warnings and the config files actually loaded. |
commands.daily
| Option | Type | Default | Possible values | Description |
|---|---|---|---|---|
instances | bool | false | true | false | Add a per-project sub-grouping under each date. |
project | string | "" | project name or alias | Filter to a single project. |
projectAliases | string | "" | key=Label,key=Label,… | Comma-separated map renaming long project IDs in output (e.g. uuid-123=My API,long-name=Backend). |
order | enum | desc | asc | desc | Row ordering. |
since | string | "" | YYYYMMDD | Default start date. |
until | string | "" | YYYYMMDD | Default end date. |
commands.weekly
| Option | Type | Default | Possible values | Description |
|---|---|---|---|---|
startOfWeek | enum | monday | monday | sunday | First day of the calendar week (ISO 8601 → Monday). |
commands.monthly
| Option | Type | Default | Possible values | Description |
|---|---|---|---|---|
breakdown | bool | false | true | false | Force per-model breakdown for the monthly report only. |
commands.blocks
| Option | Type | Default | Possible values | Description |
|---|---|---|---|---|
active | bool | false | true | false | Default to showing only the currently-running block. |
sessionLength | int | 5 | 1–24 | Override the 5-hour billing-window length. |
tokenLimit | string | "" | integer-as-string ("500000") | Token threshold that triggers a visual warning in live mode. |
commands.statusline
| Option | Type | Default | Possible values | Description |
|---|---|---|---|---|
offline | bool | false | true | false | Force offline mode for the statusline command specifically (kept on by most users — the statusline runs on every keystroke and the online price fetch is too slow). |
cache | bool | false | true | false | Cache the rendered statusline output. |
refreshInterval | int | 5 | 1–60 | Re-render interval in seconds. |
Environment variables
| Variable | Purpose | Default |
|---|---|---|
CLAUDE_CONFIG_DIR | Override the Claude Code data directory (where projects/<id>/<conv>.jsonl lives). Comma-separated to read from multiple. | ~/.config/claude then ~/.claude |
CODEX_HOME | Override the Codex data directory. | ~/.codex |
OPENCODE_DATA_DIR / AMP_DATA_DIR / KILO_DATA_DIR / KIMI_DATA_DIR / QWEN_DATA_DIR | Per-agent data-dir overrides. | per-agent defaults |
DROID_SESSIONS_DIR | Droid session storage. | ~/.factory/sessions |
CODEBUFF_DATA_DIR | Codebuff / manicode. | ~/.config/manicode |
HERMES_HOME | Hermes Agent. | ~/.hermes |
PI_AGENT_DIR | pi-agent sessions. | ~/.pi/agent/sessions |
GOOSE_PATH_ROOT | Goose. | Goose default search roots |
OPENCLAW_DIR | OpenClaw. | ~/.openclaw |
COPILOT_OTEL_FILE_EXPORTER_PATH | GitHub Copilot CLI OpenTelemetry file. | none — must be set explicitly to enable Copilot |
GEMINI_DATA_DIR | Gemini CLI. | ~/.gemini/tmp |
CCUSAGE_TIMEZONE | Same as --timezone. | system tz |
CCUSAGE_OFFLINE | Same as --offline. | unset |
LOG_LEVEL | 0 (silent) … 5 (trace). Default 3 (info). | 3 |
NO_COLOR / FORCE_COLOR | Standard color-control variables. | auto-detect |
Example config — a working file for a developer who only uses Claude Code, wants Asia/Tokyo bucketing, monthly per-model breakdowns, and a 500 k token warning per 5-hour block:
{
"$schema": "https://ccusage.com/config-schema.json",
"defaults": {
"timezone": "Asia/Tokyo",
"mode": "auto",
"json": false,
"offline": false
},
"commands": {
"daily": {
"instances": true,
"order": "desc",
"projectAliases": "long-uuid-here=ContosoWeb,scratch=Throwaway Sandbox"
},
"weekly": { "startOfWeek": "monday" },
"monthly": { "breakdown": true },
"blocks": {
"tokenLimit": "500000",
"sessionLength": 5,
"active": false
},
"statusline": { "offline": true, "cache": true }
}
}
Output: (none — file content)
Daily report
ccusage daily aggregates token usage and cost by date — one row per calendar day in the chosen timezone, columns for input tokens, output tokens, cache-creation tokens, cache-read tokens, and the cost in USD. It's the default starting point for any usage investigation.
# Last ~30 days (default range)
ccusage daily
# Explicit range
ccusage daily --since 20260501 --until 20260531
# Filter to one project, with per-model breakdown
ccusage daily --project ContosoWeb --breakdown
# Group by project under each date (instance view)
ccusage daily --instances
# JSON for further processing
ccusage daily --since 20260601 --until 20260608 --json | jq '.daily[].cost' | paste -sd+ | bc
Output:
┌──────────────┬──────────────┬───────────────┬──────────────────┬──────────────┬──────────────┐
│ Date │ Models │ Input │ Output │ Cache Create │ Cost (USD) │
├──────────────┼──────────────┼───────────────┼──────────────────┼──────────────┼──────────────┤
│ 2026-06-08 │ sonnet-4-6 │ 2,341 │ 18,432 │ 1,204 │ $0.86 │
│ 2026-06-07 │ opus-4-7 │ 4,802 │ 62,107 │ 3,118 │ $4.21 │
│ 2026-06-06 │ sonnet-4-6 │ 923 │ 5,604 │ 312 │ $0.21 │
│ TOTAL │ │ 8,066 │ 86,143 │ 4,634 │ $5.28 │
└──────────────┴──────────────┴───────────────┴──────────────────┴──────────────┴──────────────┘
Weekly and monthly reports
weekly and monthly are the same aggregation rolled up to wider buckets. The week's start day is configurable (Monday by ISO default, Sunday for US calendars); the month grouping respects the same --timezone as everything else. Use --breakdown to see how spend splits across models — typically a strong signal of whether you're driving cost from Opus runs or staying inside Sonnet.
# This year, week by week, Monday start
ccusage weekly --since 20260101
# Calendar-month view with per-model split
ccusage monthly --breakdown
# US-style weeks
ccusage weekly --start-of-week sunday
# Per-instance monthly (which project burned most this month)
ccusage monthly --instances --breakdown --json | jq '.monthly[0].projects | sort_by(.cost) | reverse | .[0:5]'
Output:
┌──────────────┬─────────────────────┬──────────────┬────────────────┬──────────────┐
│ Week │ Models │ Input │ Output │ Cost (USD) │
├──────────────┼─────────────────────┼──────────────┼────────────────┼──────────────┤
│ 2026-W23 │ sonnet, opus │ 48,201 │ 621,118 │ $42.31 │
│ 2026-W22 │ sonnet │ 31,442 │ 403,807 │ $18.94 │
│ 2026-W21 │ sonnet, opus, haiku │ 52,108 │ 702,441 │ $51.07 │
└──────────────┴─────────────────────┴──────────────┴────────────────┴──────────────┘
Session report
A "session" is one full conversation thread — one JSONL file under ~/.claude/projects/<project>/<uuid>.jsonl. ccusage session aggregates per-session, showing how expensive each conversation was, which is the right view when you suspect one particular thread blew the budget.
# Top 20 most expensive sessions
ccusage session --order desc | head -25
# One specific session by UUID
ccusage session --id 3f2c91a4-e8b7-d1c9-a0f4-e6b8c2d1a3f5
# All sessions in one project, JSON
ccusage session --project ContosoWeb --json | jq '.sessions[] | {id, cost, totalTokens}' | head
Output:
┌────────────────────────────────────────┬──────────────┬───────────────┬──────────────┐
│ Session │ Project │ Total Tokens │ Cost (USD) │
├────────────────────────────────────────┼──────────────┼───────────────┼──────────────┤
│ 3f2c91a4-…-a3f5 │ ContosoWeb │ 142,318 │ $11.42 │
│ 8b7d1c9a-…-c4d6 │ ContosoAPI │ 98,204 │ $7.89 │
│ 9a1b2c3d-…-e5f6 │ Sandbox │ 71,402 │ $4.31 │
└────────────────────────────────────────┴──────────────┴───────────────┴──────────────┘
5-hour billing blocks
Claude's API bills usage in 5-hour windows — once you start a session at time T, every request in [T, T+5h) counts toward the same block. ccusage blocks surfaces those windows specifically, with --active to focus on the current one and --live for a real-time monitor that updates as you type.
# Show all blocks (last 30 days)
ccusage blocks
# Only the currently-open block (often what you want)
ccusage blocks --active
# Last 3 days
ccusage blocks --recent
# Real-time monitor — useful in a tmux pane while you're working
ccusage blocks --live --refresh-interval 5
# Warn me when this block hits 500 k tokens
ccusage blocks --active --token-limit 500000
Output:
┌─────────────────────────────────────┬───────────────┬──────────────┬─────────────┐
│ Block │ Total Tokens │ Cost (USD) │ Status │
├─────────────────────────────────────┼───────────────┼──────────────┼─────────────┤
│ 2026-06-08 14:00 → 19:00 │ 287,604 │ $14.82 │ active │
│ 2026-06-08 09:00 → 14:00 │ 401,118 │ $19.07 │ completed │
│ 2026-06-07 14:00 → 19:00 │ 512,201 │ $32.41 │ completed ⚠ │
└─────────────────────────────────────┴───────────────┴──────────────┴─────────────┘
Statusline integration
ccusage statusline prints a single compact line — total spend in the current 5-hour block, plus today's cost — designed to be embedded in a shell prompt, tmux statusline, or the Claude Code custom statusline hook. The --cache flag is important here: the statusline is rendered on every keystroke in some shells, so reading every JSONL file each time is way too slow.
# One-shot
ccusage statusline
# Hooked into Claude Code's custom statusline (~/.claude/settings.json)
# {
# "statusLine": {
# "command": "bunx ccusage statusline --cache"
# }
# }
# Embedded in starship.toml
# [custom.ccusage]
# command = "bunx ccusage statusline --cache --offline"
# when = "true"
# format = "[$output]($style) "
# style = "dim purple"
# In a tmux statusline (refreshes every 60s)
# set -g status-right "#(bunx ccusage statusline --cache --offline) | %H:%M"
Output:
🔥 $14.82 / 5h • today $26.47
JSON output and piping
Every command supports --json and emits a single structured document — array of rows for daily/weekly/monthly/session, plus a summary total. Pipe through jq for ad-hoc analysis, or feed into Datadog/Grafana/Prometheus exporters for long-term cost tracking.
# Total spend across the last 30 days
ccusage daily --json | jq '[.daily[].cost] | add'
# Days where spend exceeded $20
ccusage daily --json | jq '.daily[] | select(.cost > 20) | {date, cost}'
# Per-model breakdown for the current month, sorted by cost
ccusage monthly --breakdown --json \
| jq '.monthly[0].models | to_entries | sort_by(-.value.cost) | .[] | "\(.key): $\(.value.cost)"'
# Export today's data to a CSV
ccusage daily --since "$(date +%Y%m%d)" --until "$(date +%Y%m%d)" --json \
| jq -r '.daily[] | [.date, .totalTokens, .cost] | @csv' > today.csv
Output:
"2026-06-08",18203,12.47
Library usage (programmatic API)
ccusage exports the same data loaders as a typed library from the ccusage/data-loader subpath — useful when you want to integrate the analysis into a web dashboard, a Slack bot, or a CI check without shelling out. The functions return typed arrays you can iterate, filter, and sum in pure TypeScript.
// dashboard.ts
import { loadDailyUsageData, loadSessionData, loadMonthlyUsageData } from "ccusage/data-loader";
import type { DailyUsage, SessionUsage } from "ccusage/data-loader";
const daily: DailyUsage[] = await loadDailyUsageData({
since: "20260601",
until: "20260608",
mode: "auto",
order: "desc",
});
const totalCost = daily.reduce((sum, row) => sum + row.cost, 0);
console.log(`Last week: $${totalCost.toFixed(2)} across ${daily.length} days`);
const sessions: SessionUsage[] = await loadSessionData({ project: "ContosoWeb" });
const expensive = sessions.filter(s => s.cost > 5).slice(0, 3);
for (const s of expensive) {
console.log(`${s.sessionId}: $${s.cost.toFixed(2)} (${s.totalTokens.toLocaleString()} tokens)`);
}
Output:
Last week: $147.83 across 7 days
3f2c91a4-...-a3f5: $11.42 (142,318 tokens)
8b7d1c9a-...-c4d6: $7.89 (98,204 tokens)
9a1b2c3d-...-e5f6: $4.31 (71,402 tokens)
Cost modes and pricing
ccusage supports three cost-calculation strategies via --mode. Picking the right one matters when you want to reconcile the bill on your Anthropic console against ccusage's totals.
auto(default) — Trust the cost field the agent recorded into the JSONL if present; fall back to recomputing from tokens using the latest LiteLLM pricing table fetched at startup. Best general-purpose default.calculate— Always recompute from raw token counts. Use this when the agent's pricing snapshot is stale, or when you switched API keys between tiers (e.g. free → paid) and the JSONL cost field reflects the old tier.display— Use only what the agent recorded; never fetch live prices. Use this when you're offline, in a hermetic build environment, or auditing what the agent thought it was being charged at the time.
ccusage daily --mode auto # default
ccusage daily --mode calculate # recompute from tokens
ccusage daily --mode display # use only stored cost
ccusage daily --mode calculate --offline # recompute, but with the bundled pricing table only
Output:
(daily report rendered; the `Cost (USD)` column reflects the chosen strategy)
Common pitfalls
ccusagereads only what the agents have actually written to disk. A live session whose JSONL hasn't been flushed yet won't appear until the agent next syncs. If "today" looks empty, run any Claude Code command and re-check.- Date format is strict
YYYYMMDD— no dashes, no slashes.--since 2026-06-01silently parses to an invalid date and you get an empty report with no warning. --mode autorequires network on first run to fetch the LiteLLM pricing table. Use--offline(orCCUSAGE_OFFLINE=1) in CI runners that have no egress.- The 5-hour billing window starts at the first request of a session, not on the hour. If you started typing at 14:23 your window runs to 19:23, not to 19:00. The block timestamps in the
blocksreport show the actual start, not a rounded boundary. sessionrows are per-JSONL file, not per "thread". If you/cleara conversation in Claude Code, the same session ID may receive a new file — what looks like two sessions is one logical conversation, and vice versa.statuslinewithout--cacheis slow enough to lag a shell prompt. Always pass--cacheand--offlinewhen the output is rendered on every keystroke.- Config files merge shallowly, not deeply. Setting
commands.daily.instances=truein a project config replaces the entirecommands.dailyblock from the user config; copy the keys you want to keep. - Project filtering is by directory name under
~/.claude/projects/, which is a hashed UUID by default, not the human-readable name. UseprojectAliasesin config to map them, or runls ~/.claude/projects/to find the actual key. CLAUDE_CONFIG_DIRdefaults to two paths (~/.config/claudeand~/.claude), comma-separated. If you set it to only one, the other is ignored — set both if you're not sure where Claude Code writes.- The Copilot CLI source requires
COPILOT_OTEL_FILE_EXPORTER_PATHto be set explicitly. Unlike the other agents, Copilot doesn't write a discoverable JSONL by default; you have to configure the OpenTelemetry file exporter first.
Real-world recipes
Slack-bot daily cost summary
A cron-driven script that runs at 09:00 and posts yesterday's spend to a Slack channel. Uses ccusage's JSON output piped through jq and curl.
#!/usr/bin/env bash
set -euo pipefail
YESTERDAY=$(date -u -d "yesterday" +%Y%m%d)
WEBHOOK="https://hooks.slack.com/services/T000/B000/your-token"
PAYLOAD=$(bunx ccusage daily --since "$YESTERDAY" --until "$YESTERDAY" --json \
| jq --arg d "$YESTERDAY" '{
text: "Claude Code spend for \($d): $\(.daily[0].cost // 0) over \(.daily[0].totalTokens // 0) tokens"
}')
curl -fsS -X POST -H "Content-Type: application/json" -d "$PAYLOAD" "$WEBHOOK"
Output:
ok
Hard budget cap that exits non-zero in CI
Run this as a final step in your CI workflow — if Claude Code usage exceeded a daily budget (e.g. $10), the job fails and a notification fires. Combine with GitHub Actions' if: failure() to alert.
#!/usr/bin/env bash
BUDGET_USD=10.00
TODAY=$(date -u +%Y%m%d)
SPEND=$(bunx ccusage daily --since "$TODAY" --until "$TODAY" --offline --json \
| jq '.daily[0].cost // 0')
awk -v s="$SPEND" -v b="$BUDGET_USD" 'BEGIN { exit !(s > b) }' \
&& { echo "Budget exceeded: \$$SPEND > \$$BUDGET_USD"; exit 1; } \
|| { echo "Within budget: \$$SPEND ≤ \$$BUDGET_USD"; }
Output:
Within budget: $4.27 ≤ $10.00
Per-project monthly breakdown for invoicing
A weekly cron that produces a CSV grouping the month-to-date spend by project alias — drop straight into a client invoice spreadsheet.
MONTH_START=$(date -u +%Y%m01)
TODAY=$(date -u +%Y%m%d)
bunx ccusage monthly --instances --since "$MONTH_START" --until "$TODAY" --json \
| jq -r '
.monthly[0].projects
| to_entries
| sort_by(-.value.cost)
| (["Project","Tokens","Cost USD"], (.[] | [.key, .value.totalTokens, .value.cost]))
| @csv
' > "/home/alice/invoices/$(date -u +%Y-%m)-claude.csv"
head -5 "/home/alice/invoices/$(date -u +%Y-%m)-claude.csv"
Output:
"Project","Tokens","Cost USD"
"ContosoWeb",2418207,142.31
"ContosoAPI",1124817,84.91
"Sandbox",402118,18.07
Live tmux pane while you're coding
A dedicated tmux pane that shows the current 5-hour block updated every 5 seconds — see costs accumulate as you prompt.
# Open a side pane
tmux split-window -h "bunx ccusage blocks --live --refresh-interval 5 --token-limit 500000"
Output:
┌─────────────────────────────────────┬───────────────┬──────────────┐
│ Active block │ Total Tokens │ Cost (USD) │
├─────────────────────────────────────┼───────────────┼──────────────┤
│ 2026-06-08 14:00 → 19:00 (2h left) │ 287,604 │ $14.82 │
└─────────────────────────────────────┴───────────────┴──────────────┘
[refreshing every 5s — Ctrl-C to exit]
Detect spend spikes with a one-line check
A "did anything weird happen yesterday?" guard — alert when yesterday's spend is more than 3× the trailing 7-day average.
bunx ccusage daily --since "$(date -d '8 days ago' +%Y%m%d)" --until "$(date +%Y%m%d)" --json \
| jq '
(.daily | sort_by(.date)) as $days
| ($days[:-1] | map(.cost) | add / length) as $avg
| $days[-1].cost as $today
| { avg: $avg, today: $today, ratio: ($today/$avg) }
| if .ratio > 3 then "SPIKE: today=\(.today) avg=\(.avg) (\(.ratio | floor)×)" else "ok (\(.ratio | floor)×)" end
'
Output:
"SPIKE: today=42.31 avg=11.07 (3×)"
Embed in a custom Claude Code statusline
Wire ccusage into Claude Code's own statusline hook so cost shows alongside the model name in every Claude Code session.
{
"statusLine": {
"command": "bunx ccusage statusline --cache --offline"
}
}
Output: (none — file content; the statusline renders inside Claude Code)
Sources
References consulted while writing this article. Links open in a new tab.
- ryoppippi/ccusage on GitHub — Canonical repository; source for the current version (v20.0.6, May 2026), the 15 supported coding-agent sources, the project's offline-first design, and the
binfield that registers theccusageexecutable. - ccusage docs — CLI options reference — Source for the global and per-command flag tables (
--since,--until,--mode,--breakdown,--token-limit,--live, etc.) used in Essential options. - ccusage docs — Configuration — Source for the four-tier loading-precedence chain, the JSON schema URL, and the per-OS file-location list under Configuration.
- ccusage docs — Environment variables — Authoritative list of
CLAUDE_CONFIG_DIR,CODEX_HOME,CCUSAGE_OFFLINE,CCUSAGE_TIMEZONE,LOG_LEVEL, and the per-agent data-dir overrides. - ccusage.example.json — Reference config file shipped in the repo; basis for the Example config shape, the
projectAliasessyntax, and thetokenLimit: "500000"example. - ccusage on npm — Package metadata page; source for the
bunx ccusage/npx ccusage@latest/pnpm dlxinstall paths and global-install variants in Install. - Library usage docs — Source for the
ccusage/data-loadersubpath, theloadDailyUsageData/loadSessionData/loadMonthlyUsageDataAPI, and the typed exports used in Library usage.