How the /caveman-stats Command Calculates Lifetime Token Savings
The /caveman-stats command calculates lifetime token savings by first capturing per-session snapshots that attribute output tokens to active modes and estimate savings using benchmark-derived compression ratios, then aggregating these entries from the .caveman-history.jsonl log file to produce cumulative totals across all sessions.
The open-source Caveman tool for Claude Code provides transparent token usage analytics through its /caveman-stats command. Understanding how this command calculates lifetime token savings reveals the sophisticated attribution logic that turns raw session transcripts into meaningful cost estimates. This deep dive examines the actual implementation in src/hooks/caveman-stats.js to explain the two-phase calculation process that powers your lifetime savings metrics.
The Two-Phase Architecture of Lifetime Token Savings
Phase 1: Per-Session Snapshot Generation
When executed inside a Claude Code session, the command parses the session JSONL file using parseSession (src/hooks/caveman-stats.js lines 78-106). This function extracts critical metrics including outputTokens, cacheReadTokens, turns, and the model ID from the transcript.
The function attributeByMode (lines 86-130) then distributes these output tokens across different modes based on the transition log stored in .caveman-mode-log.jsonl. This attribution ensures that token counts map to the specific mode active during generation.
Next, deriveSavings (lines 41-50) applies the benchmark compression ratios defined in the COMPRESSION constant. For modes with established benchmarks (currently only 'full' at 0.65), it calculates estimated saved tokens using the formula:
estSavedTokens = round(tokens / (1 - ratio)) - tokens
The results are written to .caveman-history.jsonl via appendFlag in the main() function (lines 92-108), storing session_id, mode, model, output_tokens, est_saved_tokens, and est_saved_usd as a JSON line.
Phase 2: Lifetime Aggregation from History Log
When invoked with --all or --since flags, the command bypasses live session parsing and reads the accumulated history. The aggregateHistory function (lines 62-84) loads .caveman-history.jsonl, optionally filters entries by date windows, and collapses the log to retain only the latest entry per session.
It then sums the output_tokens and est_saved_tokens fields across all retained entries. These summed values constitute the lifetime totals displayed by the command.
Core Implementation Details and File Paths
Primary Calculation Functions in caveman-stats.js
The src/hooks/caveman-stats.js file contains the full implementation:
parseSession(lines 78-106): Reads.jsonltranscripts and extracts token counts and model identifiers.attributeByMode(lines 86-130): Uses the mode transition log or file modification times to partition tokens by active mode.deriveSavings(lines 41-50): Applies compression ratios to estimate potential token savings.aggregateHistory(lines 62-84): Collapses history to latest-per-session and sums totals for lifetime reporting.formatHistory(lines 9-24): Renders the human-readable output including "Lifetime ... Est. tokens saved" and USD equivalents.
Supporting Infrastructure
Several adjacent files enable the calculation:
src/hooks/caveman-config.js: Provides utility functionsreadFlag,appendFlag,readHistory, andsafeWriteFlagfor persistent log management.src/hooks/caveman-mode-tracker.js: Generates the.caveman-mode-log.jsonltransition log required for mode attribution.docs/HONEST-NUMBERS.md: Documents the estimation methodology and acknowledges the limitations of benchmark-derived calculations.
Practical Usage Examples
Generate a per-session snapshot and update the lifetime log:
/caveman-stats
Display lifetime totals without parsing a live session:
caveman-stats --all
Expected output includes aggregated statistics:
Sessions: 12
Output tokens: 1 234 567
Est. tokens saved: 456 789
Filter lifetime totals to the last 7 days:
caveman-stats --all --since 7d
Generate a shareable summary for the current session:
/caveman-stats --share
This produces a formatted line like:
🪨 Saved 12 345 output tokens (~$0.19) across 34 turns this session — caveman.sh
Summary
- The caveman-stats command calculates lifetime token savings through a two-phase process: per-session estimation followed by historical aggregation.
- Per-session calculations use
attributeByModeandderiveSavingsinsrc/hooks/caveman-stats.jsto apply benchmark compression ratios (0.65 for 'full' mode) to attributed output tokens. - Lifetime aggregation relies on
aggregateHistoryreading from.caveman-history.jsonl, keeping only the latest entry per session to avoid double-counting. - The calculation writes intermediate data via
appendFlagand reads via utility functions insrc/hooks/caveman-config.js. - All figures represent estimates derived from benchmark ratios rather than precise measurements, as documented in
docs/HONEST-NUMBERS.md.
Frequently Asked Questions
What file stores the lifetime token savings data?
The .caveman-history.jsonl file in your project root stores the persistent log. Each line contains a JSON object with session_id, mode, model, output_tokens, est_saved_tokens, and est_saved_usd. The aggregateHistory function reads this file to compute lifetime totals.
How does the command avoid double-counting sessions in the lifetime total?
The aggregateHistory function (lines 62-84 in src/hooks/caveman-stats.js) collapses the history log to only the latest entry for each unique session_id before summing. This ensures that if a session is snapshotted multiple times, only the most recent data contributes to the lifetime calculation.
Why is the token savings figure labeled as an "estimate"?
The savings calculation uses benchmark-derived compression ratios stored in the COMPRESSION constant. Currently, only the 'full' mode has a defined ratio (0.65). The formula round(tokens/(1-ratio)) - tokens projects what token usage might have been without the mode's compression, rather than measuring actual API call differences. See docs/HONEST-NUMBERS.md for detailed methodology limitations.
Can I calculate savings for specific date ranges?
Yes. Use the --since flag with the --all option to filter the lifetime aggregation. For example, caveman-stats --all --since 7d processes only entries from the last seven days, applying the same aggregateHistory logic to the filtered subset.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →