Comprehensive visualization and tracking for Claude Code usage metrics with multiple visualization options.
- HTML Dashboard - Standalone web-based visualization with interactive charts
- Grafana Integration - Professional monitoring dashboards with time-series analysis
- SQLite Backend - Historical data storage for advanced queries and analysis
- Docker Stack - Complete monitoring infrastructure (Prometheus + Grafana + nginx)
- Flexible Export - Daily, weekly, and monthly reports with JSON export
- Multi-Project Support - Track usage across multiple projects
- Cache Analytics - Monitor prompt caching efficiency
- Claude Code installed and configured
- ccusage CLI tool installed
- Python 3.8+ for database scripts
- Docker and Docker Compose (for Grafana stack, optional)
git clone <your-repo-url>
cd ccusage-graphsGenerate the latest usage data from Claude Code:
./refresh_data.shThis will create:
data/export.json- Daily usage datadata/export_instances.json- Per-project breakdowndata/export_latest.json- Latest snapshotindex.html- Updated HTML dashboard
Simply open the HTML file in your browser:
open index.htmlFor Grafana integration and advanced queries:
python3 create_sqlite_db.pyThis creates claude_usage.db with optimized tables and indexes.
docker compose up -dAccess Grafana at http://localhost:3000 (default credentials: admin/admin)
IMPORTANT: This tool processes local usage data and does not transmit any information externally.
The following files contain your personal usage metrics and are automatically excluded from git:
data/*.json- Generated usage exports (project names, timestamps, token counts)*.db- SQLite databases with historical dataembedded_data_temp.json- Temporary HTML dashboard data
If you fork this project or share your repository:
- ✅ Verify data files are in
.gitignore - ✅ Run
git statusto ensure no data files are staged - ✅ Check for personal paths in documentation
- ✅ Review for internal project names in examples
Usage data files may include:
- Project directory names and paths
- Usage timestamps and token counts
- Model selections (e.g., sonnet, opus, haiku)
- Repository names and locations
Never commit these files to version control or public repositories.
# Standard refresh
./refresh_data.sh
# With timezone (recommended for consistency)
CCUSAGE_TIMEZONE=America/New_York ./refresh_data.sh
# Verbose output
CCUSAGE_VERBOSE=true ./refresh_data.sh
# Filter by project
CCUSAGE_PROJECT="my-project" ./refresh_data.sh
# Date range
CCUSAGE_SINCE=20251001 CCUSAGE_UNTIL=20251031 ./refresh_data.sh
# Generate weekly and monthly reports
CCUSAGE_WEEKLY=true CCUSAGE_MONTHLY=true ./refresh_data.sh# Create/update database
python3 create_sqlite_db.py
# Append new data (keep existing)
python3 create_sqlite_db.py --mode append
# Use different files
python3 create_sqlite_db.py --json data/export_weekly.json --db weekly.db
# Verbose output
python3 create_sqlite_db.py --verbose
# View help
python3 create_sqlite_db.py --help# Interactive SQL queries
sqlite3 claude_usage.db
# Example queries
sqlite3 claude_usage.db "SELECT date, total_cost FROM daily_usage ORDER BY date DESC LIMIT 10"
sqlite3 claude_usage.db "SELECT model_name, SUM(cost) as total FROM model_usage GROUP BY model_name"The refresh script supports these environment variables:
| Variable | Description | Default |
|---|---|---|
CCUSAGE_DATA_DIR |
Data directory path | data |
CCUSAGE_TIMEZONE |
Timezone for date grouping | System timezone |
CCUSAGE_PROJECT |
Filter to specific project | All projects |
CCUSAGE_SINCE |
Start date (YYYYMMDD) | All history |
CCUSAGE_UNTIL |
End date (YYYYMMDD) | Today |
CCUSAGE_VERBOSE |
Verbose output | false |
CCUSAGE_WEEKLY |
Generate weekly report | false |
CCUSAGE_MONTHLY |
Generate monthly report | false |
Create a .env file for persistent configuration:
CCUSAGE_TIMEZONE=America/New_York
CCUSAGE_VERBOSE=true
CCUSAGE_WEEKLY=true
CCUSAGE_MONTHLY=trueThen run:
source .env && ./refresh_data.shBest for: Quick standalone visualization, sharing reports
Features:
- Interactive charts (Chart.js)
- Token usage trends
- Cost analysis by model
- Cache efficiency metrics
- Embedded data (works offline)
Access: open index.html
Best for: Continuous monitoring, team dashboards, alerting
Features:
- Real-time updates
- Time-series analysis
- Custom queries
- Multi-dashboard support
- Alerting capabilities
Access: http://localhost:3000 (after docker compose up -d)
Available Dashboards:
grafana-dashboard.json- JSON-based metricsgrafana-sqlite-dashboard.json- SQLite-based metrics (recommended)
See grafana-sqlite-setup.md for detailed setup.
Best for: Custom analysis, data export, integration
Features:
- Fast queries
- Historical analysis
- Data export (CSV, JSON)
- Integration with other tools
Schema:
daily_usage- Daily aggregated metricsmodel_usage- Per-model breakdown
| File | Description | Updated By |
|---|---|---|
data/export.json |
Daily usage data | refresh_data.sh |
data/export_instances.json |
Per-project breakdown | refresh_data.sh |
data/export_latest.json |
Latest snapshot | refresh_data.sh |
data/export_weekly.json |
Weekly aggregates (optional) | refresh_data.sh |
data/export_monthly.json |
Monthly aggregates (optional) | refresh_data.sh |
claude_usage.db |
SQLite database | create_sqlite_db.py |
index.html |
HTML dashboard | refresh_data.sh |
Update data hourly:
0 * * * * cd /path/to/ccusage-graphs && ./refresh_data.sh && python3 create_sqlite_db.py#!/bin/bash
# daily-summary.sh
./refresh_data.sh
python3 create_sqlite_db.py --verbose > /tmp/ccusage-summary.txt
mail -s "Claude Code Daily Usage" you@example.com < /tmp/ccusage-summary.txtInstall the ccusage CLI:
npm install -g @anthropic/ccusageThe ccusage command may have failed. Run manually:
ccusage daily -j- Verify SQLite database has data:
sqlite3 claude_usage.db "SELECT COUNT(*) FROM daily_usage" - Restart Grafana:
docker compose restart grafana - Check Grafana data source configuration
The refresh script updates the embedded data. Run:
./refresh_data.shRemove the old database and recreate:
rm claude_usage.db
python3 create_sqlite_db.pyThe system automatically supports new Claude models. Currently tracked models include:
- Claude Opus 4.1 (
claude-opus-4-1-20250805) - Claude Sonnet 4.5 (
claude-sonnet-4-5-20250929) - Claude Haiku 3.5 (
claude-3-5-haiku-20241022)
New models are automatically detected from ccusage output.
The dashboard tracks prompt caching metrics:
- Cache Creation Tokens - Tokens cached for reuse
- Cache Read Tokens - Tokens read from cache
- Cache Hit Rate - Percentage of tokens served from cache
High cache hit rates (>80%) indicate efficient prompt caching.
Costs are calculated based on:
- Input/output token counts
- Cache creation/read tokens
- Per-model pricing
- Real-time API pricing (when available)
The --mode calculate flag in ccusage forces recalculation of costs.
ccusage-graphs/
├── data/ # Generated data files (gitignored)
├── refresh_data.sh # Main refresh script
├── create_sqlite_db.py # SQLite database creator
├── index.html # HTML dashboard
├── docker-compose.yml # Grafana stack
├── grafana-dashboard.json # Grafana dashboard config
├── grafana-sqlite-dashboard.json # SQLite-based dashboard
├── grafana-setup.md # Setup guide
└── README.md # This file
- Test changes with
./refresh_data.shandpython3 create_sqlite_db.py - Verify HTML dashboard loads correctly
- Test SQLite database creation
- Update documentation if adding features
-- Top 5 most expensive days
SELECT date, total_cost, total_tokens
FROM daily_usage
ORDER BY total_cost DESC
LIMIT 5;
-- Cost by model
SELECT model_name,
SUM(cost) as total_cost,
SUM(input_tokens + output_tokens) as total_tokens
FROM model_usage
GROUP BY model_name
ORDER BY total_cost DESC;
-- Weekly cost trends
SELECT strftime('%Y-%W', date) as week,
SUM(total_cost) as weekly_cost
FROM daily_usage
GROUP BY week
ORDER BY week DESC;
-- Cache efficiency over time
SELECT date,
cache_read_tokens,
total_tokens,
ROUND(100.0 * cache_read_tokens / total_tokens, 1) as cache_hit_pct
FROM daily_usage
WHERE cache_read_tokens > 0
ORDER BY date DESC;# Export to CSV
sqlite3 -header -csv claude_usage.db "SELECT * FROM daily_usage" > usage.csv
# Export to JSON
sqlite3 claude_usage.db "SELECT json_group_array(json_object(
'date', date,
'cost', total_cost,
'tokens', total_tokens
)) FROM daily_usage" > usage.jsonThis project builds on excellent open source tools:
- ccusage CLI - MIT License - Claude Code usage data export
- Python 3.8+ - Standard library only (PSF License)
- Bash - Standard Unix shell
- Chart.js (v4.4.1) - MIT License - JavaScript charting library
- Docker - Apache 2.0 - Containerization platform
- Prometheus (v2.48.0) - Apache 2.0 - Metrics collection
- Grafana (v10.2.2) - AGPL v3 - Dashboards and visualization
- JSON Exporter (v0.6.0) - Apache 2.0 - JSON to Prometheus metrics
- nginx (v1.25-alpine) - 2-clause BSD - Web server
- Anthropic for the Claude Code platform and ccusage tool
- The Prometheus and Grafana communities for excellent monitoring tools
- Chart.js community for visualization capabilities
All dependencies use permissive licenses compatible with MIT.
MIT License - See LICENSE file for details
For issues or questions:
- Check Troubleshooting section
- Review ccusage documentation
- Open an issue on GitHub
- Enhanced refresh script with comprehensive error handling
- Added timezone and project filtering support
- Improved SQLite script with validation and statistics
- Added support for weekly/monthly reports
- Enhanced documentation
- Added cache efficiency tracking
- Support for new Claude models (Opus 4.1, Sonnet 4.5)
- HTML dashboard with Chart.js
- Grafana integration
- SQLite database support
- Docker compose stack