A self-hosted analytics dashboard for Claude Code. Parses your local session transcripts, calculates hypothetical API costs, and generates an interactive HTML dashboard.
Disclaimer: Unofficial, community-built tool. Not affiliated with or endorsed by Anthropic.
Upgrading from 0.8.x? Your existing
config.jsonkeeps working and no migration step is required. See MIGRATION.md for what changed, including how to restore the previous color scheme.
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
Highlights:
- Five focused tabs - Token & API Value, Plan & Billing, Activity & Projects, Sessions, Insights & System; card-based interface with light / dark themes
- Cost & token analytics - API-equivalent cost, full token breakdown (input / output / cache-read / cache-write), cache efficiency, plan vs. actual usage
- Metric toggle - Switch the daily and cumulative charts between USD, your billing currency, and consumed tokens (input + output); the money KPI follows along
- Cache health & anomaly detection - Idle-gap (TTL) overhead tracking plus detection of no-gap cache invalidations like the 2026 Claude Code cache bugs, with a per-day flush chart as an early-warning signal
- Session replay & table - Interactive node-graph with timeline playback, plus a searchable, sortable session table with CSV / XLSX / Markdown / ZIP export
- Multi-attribute filtering - Range sliders for tokens, cost, duration, tool calls, agent dispatches, errors; one-click presets and persistent state across reloads
- Limits & plan recommendation (beta) - Detects rate-limit and server-overload events from transcripts, 5-hour rolling-window tracker, empirically calibrated plan-tier suggestion
- Per-tool token attribution - Output tokens and cost broken out by tool per session, plus a separate reasoning bucket; live-recomputed donut on the dashboard
- Privacy - F2 anonymization mode for screenshots,
--no-memoriesflag to exclude project memory content - Theming - Light / dark / system theme, optional
custom.cssrecolors the UI and charts live without touching source - Multi-user / migration - Merge multiple
~/.claudedirectories or import data from old machines; automatic session deduplication
Full feature list
- Global time-range filter (All / 7D / 30D / 90D / 1Y) and project search across the whole dashboard
- Plan-cost reference rescales proportionally to the selected range
- Hash-based deep links for tabs (e.g.
index.html#sessions) survive a full page reload - Mobile-responsive layout; data tables become stacked, labeled cards on small screens
- Universal column sorting on every data table; resizable columns (drag to size, double-click to auto-fit) on the project and plans tables
- KPI band at the top of the tab: API equivalent (with savings delta), sessions, messages, output tokens, cache hit rate
- Metric toggle USD / billing currency / Tokens for the daily by-model chart and the cumulative chart: the token view counts input + output (cache excluded), the currency view converts with your per-billing-cycle exchange rate, and the API-equivalent KPI follows the selected currency
- Daily API value by model (stacked), cumulative curve, API value by token type, model detail table
- Daily and cumulative series are bucketed by the day work actually happened: a session spanning midnight has its tokens, cost, and messages split across the real calendar days
- Estimated-pricing notice when a model in your data is missing from the price table
- Cost savings analysis vs. your subscription plan: savings, ROI, and cost-per-day per billing cycle
- Per-billing-cycle slicing (monthly cycles even for annual plans)
- In-progress billing period framed with its real end date, spend so far, and a projected end-of-cycle API value / ROI
- USD / local-currency toggle
- Limits timeline integrated into the tab, so rate-limit events appear in billing context
- GitHub-style activity heatmap
- Message patterns: hourly, weekday, daily messages and sessions in one dual-axis chart; hour-of-day and weekday are attributed to each message's actual local timestamp, so off-hours and multi-day sessions land in the right bucket
- Top projects table with per-project detail pages including memories and workflow timeline
- Expandable filter panel with range sliders + number inputs for tokens, cost, duration, message count, cache efficiency, tool calls, agent dispatches, errors
- One-click presets ("long sessions", "high-cost sessions", etc.)
- Free-text search across project / session id
- Active-filter chip row with per-chip clear; state persists across reloads
- Sortable, resizable session table; sessions that span more than one calendar day are badged in the date column
- Per-session detail pages with chat replay and Markdown / CSV / XLSX / ZIP export
- Per-session cache-efficiency badge and flush counter
- Chat replay marks errors, compactions, slash commands, interrupts, and rejected tool calls; multi-select event filters, a thinking indicator, and output tokens attributed to each slash command
- Chat replay inserts day-divider rows for multi-day sessions, and the date carries into the copy-to-clipboard and Markdown exports
- Interactive canvas-based replay with node graph and particle animations
- User node + bidirectional message flow, Chat node with wait-time indicator
- Play/pause timeline (starts paused), fullscreen mode, live message and tool-call counters
- Theme-aware canvas (grid, nodes, icons switch with the theme)
- Per-tool output tokens and cost split per session, plus a separate reasoning bucket
- Dashboard donut for tool-share that recomputes live when filters change
- Largest-remainder allocation prevents fractional drift across many small turns
- Rate-limit and server-overload events detected from transcripts; legend distinguishes explicit API markers from heuristic signals
- 5-hour rolling-window tracker (matches Anthropic's enforcement)
- Weekly hit-count summary
- Idle-gap correlation with short / medium / long buckets
- Plan-tier recommendation with empirical per-day calibration
- Numbered sub-navigation: Cache & Tokens, Agents, Errors & Reliability, Tools & Plugins, Storage & Files, Workflows
- Cache & Tokens: cache-efficiency KPIs and per-day box plot, output-token share by tool, output tokens by activity, plus the cache anomaly card (idle-gap overhead and no-gap flush events) and a "Cache Flushes per Day" chart
- Cache anomaly detection separates TTL/idle-gap flushes from no-gap invalidations (the cache was rebuilt although it cannot have expired - the pattern behind the 2026 Claude Code cache bugs); compaction rebuilds are excluded to avoid false alarms
- Agents: subagent type and dispatch distribution, task overview
- Errors & Reliability: error breakdown by source (backend / tool / user / hook), category, and tool
- Tools & Plugins: tool usage, installed plugins
- Storage & Files: storage breakdown, file snapshots, todos
- Workflows: plan-mode plans table, skills and hooks, git operations
- Light / dark / system theme toggle
- Optional
public/custom.cssoverrides colors and fonts; the example file ships every build, and accent changes recolor the UI and charts live without a rebuild
- F2 anonymization mode (extends to source labels, plan titles, skills, hooks, project memories)
--no-memoriesflag excludes project memory content from the build- Configurable display name, empty-session filter, optional Session Flow hide-switch
-
Clone the repository
git clone https://github.com/AeternaLabsHQ/claude-code-stats.git cd claude-code-stats -
Create your configuration
cp config.example.json config.json
Edit
config.jsonto match your subscription plan and preferences. -
Run the extractor
python3 extract_stats.py
-
Open the dashboard
open public/index.html # macOS xdg-open public/index.html # Linux start public/index.html # Windows
See config.example.json for all options:
| Key | Type | Default | Description |
|---|---|---|---|
language |
string |
"en" |
UI language ("en" or "de") |
display_name |
string |
"" |
Account name shown in the dashboard header (overrides the auto-detected one) |
source_label |
string |
"current" |
Label for the local ~/.claude source in session metadata |
week_anchor |
string |
"mon" |
Weekday ("mon".."sun") your weekly rate limit resets on; sets the weekly bucketing for the limits tracker and the week markers on the charts |
hide_session_flow |
bool |
false |
Hide the Session Flow visualization (for screenshots/recordings) |
plan_history |
array |
[] |
Your subscription plan history |
plan_capacity_override_pro_usd |
number |
null |
Manual per-window USD capacity of the Pro tier for the plan recommendation; overrides the empirical calibration (Max 5x / 20x scale Γ5 / Γ20) |
migration.enabled |
bool |
false |
Enable data from a migration backup |
migration.label |
string |
"" |
Label for migrated sessions (e.g. "archive:laptop") |
migration.dir |
string |
null |
Path to migration backup directory |
additional_sources |
array |
[] |
Extra ~/.claude directories to merge (multi-user) |
Each entry in plan_history represents a subscription period:
{
"plan": "Max 20x",
"start": "2026-04-27",
"end": null,
"cost_local": 214.2,
"currency_symbol": "β¬",
"cost_usd": 200.0,
"billing_day": 27,
"billing_cycle": "monthly"
}end: nullmeans the plan is currently activecost_local+currency_symbolare display values (what you actually pay, in any currency). The legacy fieldcost_euris still accepted as a fallbackcost_usddrives the savings / ROI math against API-equivalent valuebilling_daydetermines billing cycle boundaries for cost analysisbilling_cycleis"monthly"(default) or"annual". Annual plans are sliced into 12 monthly cycles so a yearly upfront payment doesn't dominate a single chart bar
If you migrated Claude Code data from another machine, you can include that historical data:
{
"migration": {
"enabled": true,
"dir": "~/backups/old-machine",
"claude_dir_name": ".claude-windows",
"dot_claude_json_name": ".claude-windows.json"
}
}The script deduplicates sessions across both sources automatically.
To include Claude Code data from other users on the same machine (or any additional ~/.claude directory), add them to additional_sources:
{
"additional_sources": [
{
"label": "alice",
"claude_dir": "/home/alice/.claude",
"dot_claude_json": "/home/alice/.claude.json",
"sudo_user": "alice"
}
]
}label- Identifies the source in session metadataclaude_dir- Path to the user's.claudedirectorydot_claude_json- (optional) Path to their.claude.jsonfilesudo_user- (optional) Run reads from this source as the given user via passwordlesssudo(useful when the running user has no direct read access; requires a sudoers rule)
When sudo_user is omitted the running user needs direct read access to the referenced directories. Sessions are deduplicated and all data (sessions, plans, todos, telemetry, etc.) is merged into the dashboard.
The calibrated domain logic (costs, cache anomalies, limits, attribution) is available as a stdlib-only package claudestats_core. extract_stats.py is the CLI driver on top of it; other consumers can install the package directly:
pip install "claudestats-core @ git+https://github.com/AeternaLabsHQ/claude-code-stats@v1.0.0"Settings (week anchor, plan history, locale) are configured via claudestats_core.settings.configure(...); without a call, sensible defaults apply.
You can recolor the dashboard without editing the source. Every build ships public/custom.css.example with the full list of overridable design tokens (the new design plus the legacy chart variables) for light, dark, and prefers-color-scheme.
cp public/custom.css.example public/custom.css
# then edit public/custom.cssThe generated pages load public/custom.css after the inlined stylesheet, so any rule you put there wins the cascade. The builder only creates public/custom.css when it does not already exist, so your edits survive every rebuild.
The example file also ships ready-made accent presets. Classic Indigo restores the color scheme used up to 0.8.x; uncomment the block and reload, no rebuild needed.
Important
Theme variables are scoped to html.theme-light .vc, html.theme-dark .vc, and body.vc-page. Target those selectors (not bare .vc) or your overrides will lose specificity to the built-in theme rules. The example file shows the right shape.
The script generates files in the public/ directory:
index.html- Interactive dashboard (open in any browser)dashboard_data.json- Raw aggregated data (for custom analysis)custom.css/custom.css.example- Your styling overrides and the reference token list (see Custom Styling)projects/- Per-project detail pagessessions/- Per-session detail pages with chat replay
Deploying only index.html produces a dashboard with broken detail-page links and no theming. Copy the whole public/ directory.
To auto-refresh the dashboard periodically:
*/10 * * * * cd /path/to/claude-stats && python3 extract_stats.py 2>&1 >> update.logWarning
The generated dashboard may contain sensitive data: source code snippets, file paths, API keys, project memories, conversation history, and internal notes. Do not publish the output to the public internet or any unsecured location. Use authentication or keep it local. Use --no-memories to exclude project memory content. Press F2 in the dashboard to toggle anonymization mode for screenshots.
Claude Code automatically deletes session transcript files older than 30 days on every startup (docs). Your history.jsonl (prompt recall) is kept, but the detailed JSONL transcripts in ~/.claude/projects/ - which this dashboard depends on for cost calculation, token breakdowns, and session replay - are permanently removed.
To preserve your data, add cleanupPeriodDays to your ~/.claude/settings.json (settings reference):
{
"cleanupPeriodDays": 99999
}Caution
Without this setting, you will silently lose historical session data every time Claude Code starts. There is no recovery mechanism - once the files are deleted, the cost and token data they contained is gone. If you use additional_sources or migration, apply this setting on every machine.
Note
Do not set the value to 0 - this disables transcript persistence entirely (#23710). The minimum allowed value is 1.
- Python 3.8+
- No external dependencies (stdlib only)
- Claude Code installed with session data in
~/.claude/
The dashboard supports English and German. Set "language": "en" or "language": "de" in your config.json.
To add a new language, create a file in locales/ following the structure of locales/en.json.
See CHANGELOG.md for the full release history.
MIT. Copyright (c) 2026 Aeterna Labs.
The bundled fonts (Manrope, JetBrains Mono) are licensed separately under the SIL Open Font License 1.1; see assets/fonts/README.md.





