Stats heatmap counts a day active only if a session STARTED that day — days spent entirely in resumed sessions show 0 and break the streak

Status Fixed / completed
Reported on v2.1.165
Maintainer reply ✓ Yes — bcherny
Activity 3 comments · opened Jun 5, 2026 · closed Aug 20, 2026
💡 Likely answer: A maintainer (bcherny, collaborator) responded on this thread — see the highlighted reply below.

Preflight Checklist

  • [x] I have searched existing issues and this hasn't been reported yet
  • [x] This is a single bug report (please file separate reports for different bugs)
  • [x] I am using the latest version of Claude Code

What's Wrong?

The usage stats screen (heatmap / current streak) appears to bucket
activity by the session's START date rather than by each message's own
timestamp.
Repro: work for a full day entirely inside a long-running session that
was started on an earlier day (resume across midnight, no new session
that day). The day shows 0 activity in the heatmap even though the
transcript contains real user/assistant messages timestamped that day,
and the current-streak counter breaks at it.
Concrete case: a day with 4 sessions / 428 message-lines (verified in
~/.claude/projects/**/*.jsonl, timestamps 06:49–17:25 UTC) rendered as
"0" because zero sessions had their first message on that date — all
activity lived in sessions started 5 days earlier.
Expected: a day is "active" if any message timestamp falls on it,
regardless of when the containing session started.
Env: claude-code 2.1.165, macOS.

What Should Happen?

A day in the usage stats should count as "active" if any message in any
transcript has a timestamp on that calendar day — regardless of when the
session that contains it was started.

Activity should be attributed per-message-timestamp, not per-session-
start date. A day worked entirely inside a long-running session that was
resumed from an earlier day should still light up in the heatmap and keep
the current streak intact.

Error Messages/Logs

A day in the usage stats should be counted as "active" if any message in
any transcript has a timestamp on that calendar day — regardless of when
the containing session was started.

Currently the heatmap / streak counter appears to bucket activity by the
session's START date, so a day spent entirely inside a long-running
session that was resumed from an earlier day shows 0 activity and breaks
the current-streak counter, even though that day's transcript contains
real user/assistant messages.

Expected: activity is attributed per-message-timestamp, not per-session-
start. Days worked entirely within resumed sessions should light up in
the heatmap and keep the streak intact.

Steps to Reproduce

  1. Start a Claude Code session on day A (e.g. May 26) and do some work.
  2. Keep that same session running and resume it over the following days

WITHOUT starting any new session — i.e. on day B (e.g. May 31) do all
your work inside that already-open session, across the midnight
boundary. (No new session has its first message on day B.)

  1. Confirm real activity exists on day B: the transcript files in

~/.claude/projects/**/*.jsonl contain user/assistant messages with
timestamps on day B (in my case 4 sessions, 428 message-lines,
06:49–17:25 UTC).

  1. Open the usage stats / heatmap screen.

Result: day B shows 0 activity in the heatmap and the current-streak
counter breaks at day B — even though day B has real messages. Every
neighbouring day (which had at least one session START that day) is
counted correctly. The only distinguishing factor of day B is that zero
sessions had their FIRST message on it.

Env: claude-code 2.1.165, macOS.

Claude Model

None

Is this a regression?

Yes, this worked in a previous version

Last Working Version

_No response_

Claude Code Version

claude-code 2.1.165

Platform

Anthropic API

Operating System

macOS

Terminal/Shell

Terminal.app (macOS)

Additional Information

_No response_

View original on GitHub ↗

3 Comments

NvMayMay · 2 months ago

Confirming this on the CLI (/usage → Stats), v2.1.170, WSL2 / Ubuntu 24.04.

The bug is demonstrable from /usage's own numbers without any external tooling. It reports two things that can't both be true:

Longest session: 5d 10h 25m ← a single session spanning 5+ days
Current streak: 1 day
Active days: 16 / 734
Longest streak: 9 days

A 5-day session alongside a 1-day current streak only makes sense if a day is credited to the session's start date instead of to each calendar day its messages land on - exactly as described here.

Ground truth from the in-content timestamps over the same window: 34 consecutive active days (2026-05-19 → 2026-06-21), zero gaps. /usage shows 16 active and a 1-day streak.

Anyone can reproduce the true count:

find ~/.claude/projects -name '*.jsonl' \
-exec grep -ho '"timestamp":"[0-9-]\{10\}' {} + \
| sed 's/.*"//' | sort -u | wc -l

(Likely compounded by UTC vs local-tz day-bucketing, as #67085 notes.) +1 - the fix is to bucket active-days/streak/heatmap by per-message timestamp, not session start date.

nafi052 · 1 month ago

Adding my case to the pile, because apparently this bug has more open duplicates than my streak had days.

The crime scene:

  • July 21st: hours of work, dozens of typed messages (08:46-10:46 UTC, verified in my local transcript), real tokens burned inside a session created July 17th.
  • The analytics' verdict: inactive. Heatmap: empty square. My 23-day streak: executed without trial.
  • My offense, as this issue correctly diagnosed: I failed to perform the sacred daily ritual of opening a new chat. I just... used the product. Rookie mistake.

The truly impressive part is the response infrastructure:

  • This issue (#65611) - open, describes the exact root cause. No fix.
  • #67085, #76885, #71549, #75966 - same bug, rediscovered independently by user after user, like some kind of distributed QA team you're not paying.
  • #72583, #78872, #64725 - closed cousins. The bug survived them all.
  • My support conversation (ID 215475185708539) - escalated to a human agent on July 22nd. It has now been 6 days. The human remains theoretical.
  • My in-app bug report (41d4f5d0-ef02-465e-93bc-f80f9452d258) - acknowledged by a dialog box, then silence.

And let's talk about the plain-reading problem: nowhere does the UI say "streak = days you opened a new chat." It says "Current streak" next to "Active days". By any honest reading of those words, a day full of typed messages is an active day. If the intended definition really is "session-start days only," that's not a streak counter, it's a chat-opening counter - and it should either say so or be fixed. Since you never defined it otherwise, simple common sense says activity must count, new chat or not.

There's also a money angle here, not just hurt feelings: streaks are a retention mechanic. People keep paid subscriptions partly to not break them - I kept my Pro subscription with that streak in mind. If the mechanic that nudges users to stay subscribed miscounts their activity and wipes weeks of it, that's a paid feature misrepresenting the very usage you bill us for.

So to summarize: the streak feature punishes long focused sessions (i.e., your heaviest users), the bug is documented across at least seven issues, and every official reporting channel leads to the same quiet void.

Asks, same as everyone above:

  1. Count active days by activity, not by session-start date.
  2. Retroactively restore streaks for affected users. You have the usage data - that's how you bill us.
  3. Have literally any human acknowledge any of these threads.

Meanwhile my stats page cheerfully informs me I've used 201x more tokens than Harry Potter and the Philosopher's Stone. Two hundred and one Harry Potters, and I'm marked inactive. Even Voldemort got more recognition.

bcherny collaborator · 9 days ago

Tested this on 2.1.233 (Linux) by constructing your exact scenario: a transcript whose session started on day A (Aug 12) with real user/assistant messages timestamped on day B (Aug 16), where no session had its first message on day B, plus a control session starting Aug 17.

On 2.1.233 the stats screen counts day B correctly: it lights up in the heatmap, "Active days" includes it, and it forms a 2-day streak with the following day. Activity is now attributed per-message-timestamp, so days worked entirely inside a resumed session count as active.

This was fixed in a recent release after the 2.1.165 you reported from (changelog). Note the fix applies going forward from cached history — if a past day still shows empty, the cached buckets from the old version may persist.

Closing — please reply to reopen if you still see a missing day on the current release.

🤖 Generated with Claude Code