Attribution vs the server window
Your local count and the window that 429s you are not the same number
If ccusage reads 5% and claude.ai still tells you to come back later, nothing is broken. The two tools attribute your usage to different things. One sums tokens on your clock. The other scores you across seven rolling windows on its clock, and stops you on whichever fills first.
Direct answer (verified 2026-05-21)
Local counters attribute one token sum to wall-clock time. Anthropic's server attributes each request across up to seven independent rolling windows (the rolling 5-hour window, the weekly window, plus per-model and per-surface weekly windows), each with its own utilization score and its own reset clock. The limiter blocks on whichever window hits 100% first, so the number that stops you is rarely the one your local count maps to.
Source of truth: claude.ai/settings/usage, rendered from the internal /api/organizations/{uuid}/usage endpoint.
What the server actually returns
This is the response behind the usage page, fetched with your own session cookie. It is not a token total. It is a list of windows, each already weighted, each with its own clock.
Values above are illustrative of the shape, not your account. The field names are exact: they are the keys claude-meter parses on every poll.
The seven windows, named
You do not have to take my word for the count. Here is the struct claude-meter deserializes the response into, straight from src/models.rs. Each field is a window. Each window carries its own resets_at.
A local-log tool parses two integers per turn and a timestamp. There is no field in your JSONL for "which of these seven windows did this turn move, and by how much." That information is computed server-side and only ever exists in the response above. That is the uncopyable part: claude-meter reports the windows because it reads them, not because it estimates them.
How one turn becomes four windows
Follow a single Opus prompt from your terminal to the rate limiter. This is where local attribution and server attribution split apart.
You send one Opus turn in Claude Code
Locally, that turn appends a single row to ~/.claude/projects/*.jsonl: input_tokens, output_tokens, a timestamp. ccusage adds those two numbers to a running total. One bucket, one clock.
The server fans that one turn out
Same request hits five_hour, seven_day, seven_day_opus, and (because Claude Code authenticates over OAuth) seven_day_oauth_apps. One turn, attributed to four windows at once.
Each window weights it differently
The server applies a model multiplier and surface weighting before incrementing each utilization float. The Opus window climbs faster than the all-models window from the identical turn.
Each window resets on its own clock
five_hour rolls off ~5 hours after the request that opened the window. The seven_day family rolls on a weekly anchor. Your local file has no idea which clock applies.
The limiter blocks on the first to hit 100%
If seven_day_opus is at 96% and your local sum reads 5%, you get a 429. The number that stops you was never on your machine. That is the attribution gap.
Two ways to attribute the same usage
ccusage and Claude-Code-Usage-Monitor read your local data well. They were built to answer a token question, and they answer it. The window question lives somewhere they cannot reach.
| Feature | Local token counter | claude-meter (server windows) |
|---|---|---|
| What gets counted | A sum of input_tokens + output_tokens parsed from local JSONL | The server's own utilization float per window, weighted before you see it |
| How many buckets | One number, one running total | Up to seven named windows scored in parallel on every request |
| Time attribution | Your machine's wall clock and file timestamps | Each window's own resets_at, anchored server-side, not to your clock |
| Which one rate-limits you | Cannot tell; it has no window concept | Whichever window crosses 100% first; claude-meter shows all of them |
| Per-model splits (Opus vs Sonnet) | Lumped into one total | seven_day_opus and seven_day_sonnet tracked separately |
| Other surfaces (browser chats, agents) | Invisible; only sees Claude Code's local files | Counted by the server and surfaced; nothing hides off-machine |
Not a knock on local-log tools. They estimate token volume; claude-meter reads the enforced windows. Different axes, both useful.
When the local counter is the right tool
If your question is "how many tokens did this refactor cost" or "which session was the expensive one," a local-log tool is the better answer. It walks every turn in your JSONL and gives you a clean per-session breakdown that the usage endpoint does not expose. For cost accounting on local data, reach for ccusage.
If your question is "why did I just get a 429 when I barely used anything" or "how long until the wall clears," that answer only exists in the seven windows. That is the gap claude-meter fills, and it is the gap a token estimate cannot close no matter how good the estimate is.
Still not sure which window keeps stopping you?
Walk through your own usage endpoint with me and I'll show you which of the seven windows is the real wall.
Questions people actually ask
Frequently asked questions
What does 'usage attribution vs server window' actually mean?
Attribution is the act of assigning a unit of usage to a bucket. A local tool like ccusage attributes your tokens to one running total keyed to your machine's clock. The server attributes the same request to up to seven named rolling windows, each with its own utilization score and its own reset time. The question 'where does this turn count?' has one answer locally and up to seven answers on the server. Rate limiting happens on the server's answer, not yours.
Why does ccusage say 5% used while claude.ai rate-limits me?
Because they are attributing to different things. ccusage sums the input and output tokens it finds in your local JSONL files and divides by an assumed cap. The server does not rate-limit on that sum. It rate-limits on whichever of its rolling windows crosses 100% first, after applying model and surface weights you never see. A single heavy Opus week can push seven_day_opus to 100% while your raw token count looks modest. There is no bug; the two systems attribute usage on different axes.
How many windows does the server actually track?
claude-meter deserializes seven: five_hour, seven_day, seven_day_sonnet, seven_day_opus, seven_day_oauth_apps, seven_day_omelette, and seven_day_cowork, plus a separate extra_usage block for metered dollar spillover. You can see the exact struct in claude-meter/src/models.rs. Anthropic can add or rename windows; claude-meter reads whatever the endpoint returns rather than guessing from token math.
Can a local-log tool ever match the server window?
No, and not because it is written badly. The weights, the per-window splits, the surface attribution, and the reset clocks all live server-side and are never written to your JSONL. A token counter can estimate token volume well; it structurally cannot reconstruct which window you are about to hit or when it resets. Those are different jobs. ccusage answers 'how many tokens did this session burn'; claude-meter answers 'which window stops me next, and when does it clear'.
Where does claude-meter get its numbers, then?
From the same internal endpoint claude.ai/settings/usage renders: /api/organizations/{uuid}/usage. The browser extension forwards your existing claude.ai session every 60 seconds, the menu-bar app reads the response, and the numbers match the settings page because they are the settings page's numbers. No token estimation, no cookie paste, no telemetry leaving your machine.
Do I still need ccusage if I run claude-meter?
They answer different questions, so many people run both. ccusage is excellent for per-session token accounting and cost breakdowns from local data. claude-meter is for the live plan-quota picture: which of the seven rolling windows you are burning and how long until each resets. Use ccusage to understand a session's token footprint; use claude-meter to know whether your next prompt gets a 429.
Is claude-meter free and open source?
Yes. MIT licensed, no telemetry, a single HTTPS request per minute to claude.ai using your own session. The macOS menu-bar app and the browser extension are both on GitHub at github.com/m13v/claude-meter. It supports Claude Pro and Max on macOS 12+, with extensions for Chrome, Arc, Brave, and Edge.
See your real windows
One brew command, install the extension, visit claude.ai once. The menu bar lights up within a minute with the same numbers the settings page shows, all seven windows, live.
Related read: the five weights your JSONL cannot see.
Comments (••)
Leave a comment to see what others are saying.Public and anonymous. No signup.