4.6 KiB
4.6 KiB
Cost Tracking System
Mission Control now tracks real usage costs by reading OpenClaw session data and calculating costs based on actual token usage.
How It Works
- Data Collection: The
collect-usage.tsscript readsopenclaw status --jsonto get current session data - Cost Calculation: Uses model pricing table to calculate costs based on input/output tokens
- Storage: Saves snapshots to SQLite database (
data/usage-tracking.db) - API: The
/api/costsendpoint queries the database to serve real cost data to the dashboard
Model Pricing
Current pricing (as of Feb 2026):
| Model | Input ($/M tokens) | Output ($/M tokens) |
|---|---|---|
| Opus 4.6 | $15.00 | $75.00 |
| Sonnet 4.5 | $3.00 | $15.00 |
| Haiku 3.5 | $0.80 | $4.00 |
| Gemini Flash | $0.15 | $0.60 |
| Gemini Pro | $1.25 | $5.00 |
| Grok 4.1 Fast | $2.00 | $10.00 |
Pricing is defined in src/lib/pricing.ts.
Manual Collection
To collect usage data manually:
cd /root/.openclaw/workspace/mission-control
npx tsx scripts/collect-usage.ts
This will:
- Read current OpenClaw session data
- Calculate costs for each agent + model combination
- Save a snapshot to the database (replacing any existing data for the same hour)
Automatic Collection (Cron)
To set up hourly automatic collection:
cd /root/.openclaw/workspace/mission-control
./scripts/setup-cron.sh
This adds a cron job that runs every hour at minute 0.
View cron jobs:
crontab -l
View logs:
tail -f /var/log/mission-control-usage.log
Remove cron job:
crontab -e
# Delete the line containing 'collect-usage.ts'
Database Schema
CREATE TABLE usage_snapshots (
id INTEGER PRIMARY KEY AUTOINCREMENT,
timestamp INTEGER NOT NULL,
date TEXT NOT NULL, -- YYYY-MM-DD
hour INTEGER NOT NULL, -- 0-23
agent_id TEXT NOT NULL,
model TEXT NOT NULL,
input_tokens INTEGER NOT NULL,
output_tokens INTEGER NOT NULL,
total_tokens INTEGER NOT NULL,
cost REAL NOT NULL,
created_at INTEGER DEFAULT (strftime('%s', 'now'))
);
Querying the Database
Total cost today:
sqlite3 data/usage-tracking.db \
"SELECT SUM(cost) FROM usage_snapshots WHERE date = date('now');"
Cost by agent (last 30 days):
sqlite3 data/usage-tracking.db \
"SELECT agent_id, ROUND(SUM(cost), 2) as cost
FROM usage_snapshots
WHERE date >= date('now', '-30 days')
GROUP BY agent_id
ORDER BY cost DESC;"
Cost by model:
sqlite3 data/usage-tracking.db \
"SELECT model, ROUND(SUM(cost), 2) as cost
FROM usage_snapshots
WHERE date >= date('now', '-30 days')
GROUP BY model
ORDER BY cost DESC;"
Daily trend (last 7 days):
sqlite3 data/usage-tracking.db \
"SELECT date, ROUND(SUM(cost), 2) as cost
FROM usage_snapshots
WHERE date >= date('now', '-7 days')
GROUP BY date
ORDER BY date DESC;"
API Endpoints
GET /api/costs
Returns cost summary, breakdowns, and trends.
Query params:
timeframe(default:30d) - Number of days to include in aggregations
Response:
{
"today": 0.80,
"yesterday": 1.25,
"thisMonth": 12.50,
"lastMonth": 38.90,
"projected": 52.30,
"budget": 100.00,
"byAgent": [
{ "agent": "main", "cost": 5.50, "tokens": 450000, "percentOfTotal": 44 }
],
"byModel": [
{ "model": "anthropic/claude-sonnet-4-5", "cost": 8.30, "tokens": 890000, "percentOfTotal": 66 }
],
"daily": [
{ "date": "02-20", "cost": 0.80, "input": 12000, "output": 8000 }
],
"hourly": [
{ "hour": "14:00", "cost": 0.12 }
]
}
Troubleshooting
No data showing up:
- Run
npx tsx scripts/collect-usage.tsto collect initial data - Check database exists:
ls -lh data/usage-tracking.db - Query database:
sqlite3 data/usage-tracking.db "SELECT COUNT(*) FROM usage_snapshots;"
Unknown model warnings:
- Update
src/lib/pricing.tswith new model pricing - Rebuild:
npm run build - Restart:
systemctl restart mission-control
Costs seem wrong:
- Verify pricing in
src/lib/pricing.ts - Check token counts:
openclaw status --json | jq '.sessions.byAgent[].recent[].totalTokens' - Recalculate: delete database and re-collect
Future Enhancements
- Budget alerts (email/Telegram when >80% spent)
- Export reports (PDF/CSV)
- Cost forecasting with ML
- Per-session cost tracking (not just agent totals)
- Integration with OpenRouter billing API for real invoices
- Cost optimization suggestions ("switch to Haiku for heartbeats")
Created: 2026-02-20
Author: Tenacitas 🦞