Server-truth usage vs local JSONL: open your own file in 60 seconds

M
Matthew Diakonov
4 min read

Two readings, same Claude account, same minute. One says 5%, the other 429s your next prompt. Neither is broken. They are measuring two different things, and once you see both files on one screen the gap stops being mysterious.

Direct answer (verified 2026-05-21)

Local JSONL at ~/.claude/projects/<session>.jsonl records raw input_tokens and output_tokens per turn on one machine. Server-truth usage lives at claude.ai/settings/usage (which calls /api/organizations/{org}/usage) and is a weighted utilization float that includes peak-hour multiplier, attachments, tool calls, model class, and browser-chat usage. The 429 is gated on five_hour.utilization from that JSON, nothing else.

Step 1: cat your JSONL

Open a terminal. This is what local JSONL actually looks like, and why it cannot answer the question the rate limiter asks:

terminal

Step 2: curl server truth

Same minute, same account, different surface. The number Anthropic enforces is a single float behind your own session cookie:

terminal

Both readings are correct. The JSONL row knows you spent 4,000 tokens this turn. The server JSON knows you are 94% of the way through your rolling 5-hour bucket because three PDF uploads and some Opus tool calls earlier in the window already moved the float that the JSONL never recorded.

The mental shift

What you thought you were reading vs what is actually under the hood

Local JSONL is the canonical source. ccusage walks it, sums tokens, gives me a percentage. If the percentage is low, I am fine. If claude.ai 429s me anyway, something is broken.

  • Treats tokens and quota as the same number
  • Cannot see attachments, tool calls, or browser chats
  • Silently wrong during peak hours and on Opus
  • Surprises you at the wall, never before it

Three views, same minute

ccusage on the same machine. The localhost bridge ClaudeMeter exposes after polling the server endpoint. The next prompt against claude.ai. Stitched together on one screen:

The receipt

Want to do this on your own account, live?

Twenty minutes. Open DevTools on claude.ai, cat your JSONL, watch the two numbers diverge in real time, then decide whether you want the menu-bar version doing it for you.

Frequently asked

Server-truth usage vs local JSONL: what is the actual difference in one sentence?

Local JSONL records raw input_tokens and output_tokens per assistant turn on one machine; server-truth usage is the weighted utilization float Anthropic publishes at https://claude.ai/api/organizations/{org_uuid}/usage and enforces with 429s. The first is a token diary, the second is the live quota meter.

Where exactly is each one stored?

Local JSONL is on disk at ~/.claude/projects/<project>/<session>.jsonl, written by Claude Code itself, one row per turn. Server truth is JSON returned by GET https://claude.ai/api/organizations/{org}/usage, the same endpoint claude.ai/settings/usage renders its bars from. ClaudeMeter polls that endpoint once a minute through your own browser session.

If ccusage walks the JSONL and says 5%, why does claude.ai still 429 me?

Because five things land in server-truth that never appear in the JSONL: a peak-hour multiplier (weekday 5 to 11 a.m. Pacific fills the 5-hour bucket faster), per-attachment cost (a PDF upload moves the bucket far more than the prompt that uploaded it), per-tool-call cost (code execution and browsing both carry server cost on top of tokens), per-model weight (Opus burns the bucket faster than Sonnet for the same byte count), and any prompts you sent in a claude.ai browser tab on the same account. Stack two of those and the 5% reading and the 94% reading both look right.

Can I read server-truth myself without installing anything?

Yes. Open claude.ai/settings/usage in Chrome, open DevTools, watch the Network tab, find the request to /api/organizations/<uuid>/usage, copy it as cURL, run it in a terminal. The JSON body is the same one ClaudeMeter reads. The only thing ClaudeMeter adds is doing that fetch every 60 seconds and drawing it in your menu bar without you re-pasting cookies.

Does the JSONL file ever match server-truth?

Only for a narrow user: Claude Code only, no claude.ai browser chat on the same account, no attachments, no tool calls, no peak-hour sessions, and exclusively on a model whose multiplier you have memorised. For anyone outside that envelope the two numbers will disagree, sometimes by an order of magnitude, and the gap will be widest exactly when you most need to predict a 429.

Do I have to choose between ccusage and a server-truth tool?

No. ccusage is the right answer for 'which project burned how many tokens this week', because the server JSON does not know about your local directory tree. ClaudeMeter is the right answer for 'will my next prompt 429'. Most heavy users run both: ccusage in a terminal split for cost attribution, ClaudeMeter in the menu bar for live quota.

How fresh is the server-truth reading in practice?

At most 60 seconds stale, because the extension polls the endpoint once a minute. The float you read is the float the rate limiter checks, with no extra weighting added between read time and limit time. The JSONL is real-time on disk but blind to the entire weighting layer plus any browser-chat usage on the same account.

How did this page land for you?

React to reveal totals

Comments ()

Leave a comment to see what others are saying.

Public and anonymous. No signup.