Durable stats ledger independent of session jsonl files
Preflight Checklist
- [x] I have searched existing requests and this feature hasn't been requested yet
- [x] This is a single feature request (not multiple features)
Problem Statement
/stats (sessions, messages, tokens) is computed by scanning~/.claude/projects/*/*.jsonl. Any operation that removes those files
silently erases the corresponding history from stats. There are at least
three paths that hit this today:
- Default
cleanupPeriodDays: 30auto-deletes old session jsonls
(root-cause analysis in #22123 — now closed/locked).
- Auto-updates have been observed to delete jsonls (#41591).
- User housekeeping. In my case: I work in a repo with many
short-lived git worktrees, each producing a session jsonl under
~/.claude/projects/-…-claude-worktrees-<name>/<uuid>.jsonl. After a
few weeks I have 50+ project dirs for worktrees that no longer exist
on disk. Cleaning them up — the obvious thing to do — silently nukes
those sessions, messages, and tokens from /stats.
The cleanupPeriodDays: 3650 workaround stops the bleeding from path
(1) but doesn't address (2) or (3). It also turns ~/.claude/projects/
into an append-only graveyard the user can't safely curate.
Proposed Solution
Persist aggregate stats in a ledger that is independent of session-jsonl
presence. Concretely: as each session ends (or incrementally during the
session), roll up its key metrics — id, project, model, input/output/
cache tokens, message count, started_at, ended_at — and append to e.g.~/.claude/usage.jsonl (or whatever store fits best).
/stats and any future claude usage command (see #33978) read from
the ledger, not by re-scanning jsonls. The jsonls remain authoritative
for resuming a session, but their presence is no longer required for
stats to be accurate.
Benefit
- Users can archive or delete old session jsonls (defunct worktrees,
stale projects) without destroying their lifetime totals.
- Auto-cleanup (#22123) and auto-update deletion (#41591) stop being
data-loss events for stats.
- Provides a stable foundation for richer analytics (#33978) without
re-parsing 100MB+ jsonl files on every /stats invocation.
Related
- #22123 — closed/locked; root-cause analysis and suggested fix
("Separate stats storage from transient session files") that this
request formalizes.
- #41591 — same data-loss class, different trigger.
- #33978 — would build cleanly on top of a durable ledger.
This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗