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.

bash
# 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.

bash
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:

bash
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.

OptionShortMeaning
--since YYYYMMDDInclusive start of the date range. Format is exactly 8 digits, no dashes.
--until YYYYMMDDInclusive end of the date range.
--json-jEmit a single JSON document instead of the formatted table — for piping to jq, dashboards, or CI checks.
--breakdown-bShow per-model rows (sonnet vs. opus vs. haiku, GPT-4 vs. GPT-4o, etc.) under each aggregate.
--mode auto|calculate|displayCost 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|descSort direction for rows. desc (newest/largest first) is the default.
--offline-OSkip the live LiteLLM pricing fetch; use the bundled pricing table that ships with this ccusage version.
--timezone TZ-zIANA timezone for date bucketing — UTC, Europe/London, Asia/Tokyo. Defaults to the system timezone or $CCUSAGE_TIMEZONE.
--debugPrint pricing mismatches and which config file paths were tried.
--debug-samples NWhen --debug finds pricing discrepancies, show up to N sample records.
--config FILEPath to an explicit JSON config file (highest precedence after CLI flags).

Per-command flags:

CommandFlagMeaning
daily--instances / -iGroup rows by project as well as by date.
daily, session--project NAME / -pFilter to a single project (matches the directory name under ~/.claude/projects/ or the alias defined in config).
weekly--start-of-week monday|sundayWhich day starts the calendar week (ISO default = Monday).
session--id UUIDShow one specific conversation by its session UUID.
blocks--active / -aShow only the currently-active 5-hour billing window.
blocks--recent / -rLimit to blocks within the last 3 days.
blocks--token-limit NTrigger a visual warning when projected usage exceeds N tokens for the current block.
blocks--liveCurses-style live view that re-renders on a timer — pair with --refresh-interval.
blocks--refresh-interval SECHow often --live re-reads the JSONL files (default 5s).
blocks--session-length HOURSOverride the default 5-hour billing window (e.g. for testing or providers with a different window).
statusline--cacheCache 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.

OSPath(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.
macOSSame as Linux — ccusage follows XDG, not ~/Library/Application SupportThe ~/.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.jsonNo %APPDATA% support — XDG-style paths only.

Loading precedence (highest to lowest):

  1. Command-line flags (--since 20260101, --timezone UTC)
  2. --config FILE explicitly passed on the command line
  3. Environment variables (CCUSAGE_TIMEZONE, CCUSAGE_OFFLINE, CLAUDE_CONFIG_DIR, CODEX_HOME, …)
  4. Project config: ./.ccusage/ccusage.json
  5. User config: ~/.config/claude/ccusage.json
  6. Legacy user config: ~/.claude/ccusage.json
  7. 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

OptionTypeDefaultPossible valuesDescription
timezonestringsystem tzIANA tz name (UTC, America/New_York, Asia/Tokyo) or localDate-bucketing timezone for daily/weekly/monthly grouping.
modeenumautoauto | calculate | displayCost-calculation strategy (see Essential options).
breakdownboolfalsetrue | falseAlways include per-model row breakdown.
offlineboolfalsetrue | falseSkip live pricing fetch.
jsonboolfalsetrue | falseDefault to JSON output globally — useful when ccusage runs in CI.
debugboolfalsetrue | falsePrint pricing-mismatch warnings and the config files actually loaded.

commands.daily

OptionTypeDefaultPossible valuesDescription
instancesboolfalsetrue | falseAdd a per-project sub-grouping under each date.
projectstring""project name or aliasFilter to a single project.
projectAliasesstring""key=Label,key=Label,…Comma-separated map renaming long project IDs in output (e.g. uuid-123=My API,long-name=Backend).
orderenumdescasc | descRow ordering.
sincestring""YYYYMMDDDefault start date.
untilstring""YYYYMMDDDefault end date.

commands.weekly

OptionTypeDefaultPossible valuesDescription
startOfWeekenummondaymonday | sundayFirst day of the calendar week (ISO 8601 → Monday).

commands.monthly

OptionTypeDefaultPossible valuesDescription
breakdownboolfalsetrue | falseForce per-model breakdown for the monthly report only.

commands.blocks

OptionTypeDefaultPossible valuesDescription
activeboolfalsetrue | falseDefault to showing only the currently-running block.
sessionLengthint5124Override the 5-hour billing-window length.
tokenLimitstring""integer-as-string ("500000")Token threshold that triggers a visual warning in live mode.

commands.statusline

OptionTypeDefaultPossible valuesDescription
offlineboolfalsetrue | falseForce 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).
cacheboolfalsetrue | falseCache the rendered statusline output.
refreshIntervalint5160Re-render interval in seconds.

Environment variables

VariablePurposeDefault
CLAUDE_CONFIG_DIROverride the Claude Code data directory (where projects/<id>/<conv>.jsonl lives). Comma-separated to read from multiple.~/.config/claude then ~/.claude
CODEX_HOMEOverride the Codex data directory.~/.codex
OPENCODE_DATA_DIR / AMP_DATA_DIR / KILO_DATA_DIR / KIMI_DATA_DIR / QWEN_DATA_DIRPer-agent data-dir overrides.per-agent defaults
DROID_SESSIONS_DIRDroid session storage.~/.factory/sessions
CODEBUFF_DATA_DIRCodebuff / manicode.~/.config/manicode
HERMES_HOMEHermes Agent.~/.hermes
PI_AGENT_DIRpi-agent sessions.~/.pi/agent/sessions
GOOSE_PATH_ROOTGoose.Goose default search roots
OPENCLAW_DIROpenClaw.~/.openclaw
COPILOT_OTEL_FILE_EXPORTER_PATHGitHub Copilot CLI OpenTelemetry file.none — must be set explicitly to enable Copilot
GEMINI_DATA_DIRGemini CLI.~/.gemini/tmp
CCUSAGE_TIMEZONESame as --timezone.system tz
CCUSAGE_OFFLINESame as --offline.unset
LOG_LEVEL0 (silent) … 5 (trace). Default 3 (info).3
NO_COLOR / FORCE_COLORStandard 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:

json
{
  "$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.

bash
# 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:

javascript
┌──────────────┬──────────────┬───────────────┬──────────────────┬──────────────┬──────────────┐
│ DateModelsInputOutputCache CreateCost (USD)   │
├──────────────┼──────────────┼───────────────┼──────────────────┼──────────────┼──────────────┤
│ 2026-06-08   │ sonnet-4-62,34118,4321,204  │      $0.86   │
│ 2026-06-07   │ opus-4-74,80262,1073,118  │      $4.21   │
│ 2026-06-06   │ sonnet-4-69235,604312  │      $0.21   │
│ TOTAL        │              │       8,06686,1434,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.

bash
# 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:

bash
┌──────────────┬─────────────────────┬──────────────┬────────────────┬──────────────┐
│ 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.

bash
# 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:

bash
┌────────────────────────────────────────┬──────────────┬───────────────┬──────────────┐
│ 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.

bash
# 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:

bash
┌─────────────────────────────────────┬───────────────┬──────────────┬─────────────┐
│ 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.

bash
# 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:

bash
🔥 $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.

bash
# 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:

arduino
"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.

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:

bash
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.
bash
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:

ini
(daily report rendered; the `Cost (USD)` column reflects the chosen strategy)

Common pitfalls

  1. ccusage reads 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.
  2. Date format is strict YYYYMMDD — no dashes, no slashes. --since 2026-06-01 silently parses to an invalid date and you get an empty report with no warning.
  3. --mode auto requires network on first run to fetch the LiteLLM pricing table. Use --offline (or CCUSAGE_OFFLINE=1) in CI runners that have no egress.
  4. 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 blocks report show the actual start, not a rounded boundary.
  5. session rows are per-JSONL file, not per "thread". If you /clear a 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.
  6. statusline without --cache is slow enough to lag a shell prompt. Always pass --cache and --offline when the output is rendered on every keystroke.
  7. Config files merge shallowly, not deeply. Setting commands.daily.instances=true in a project config replaces the entire commands.daily block from the user config; copy the keys you want to keep.
  8. Project filtering is by directory name under ~/.claude/projects/, which is a hashed UUID by default, not the human-readable name. Use projectAliases in config to map them, or run ls ~/.claude/projects/ to find the actual key.
  9. CLAUDE_CONFIG_DIR defaults to two paths (~/.config/claude and ~/.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.
  10. The Copilot CLI source requires COPILOT_OTEL_FILE_EXPORTER_PATH to 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.

bash
#!/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:

code
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.

bash
#!/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:

bash
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.

bash
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:

arduino
"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.

bash
# Open a side pane
tmux split-window -h "bunx ccusage blocks --live --refresh-interval 5 --token-limit 500000"

Output:

bash
┌─────────────────────────────────────┬───────────────┬──────────────┐
│ 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.

bash
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:

arduino
"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.

json
{
  "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 bin field that registers the ccusage executable.
  • 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 projectAliases syntax, and the tokenLimit: "500000" example.
  • ccusage on npm — Package metadata page; source for the bunx ccusage/npx ccusage@latest/pnpm dlx install paths and global-install variants in Install.
  • Library usage docs — Source for the ccusage/data-loader subpath, the loadDailyUsageData/loadSessionData/loadMonthlyUsageData API, and the typed exports used in Library usage.