Hitting your Claude weekly limit by Tuesday is a 168-hour clock, not a calendar week.
The seven-day bucket starts the moment you send your first message of the cycle and ends exactly 168 hours later. There is no Sunday-midnight reset. The exact timestamp is a field called resets_at in the JSON the server returns. Most articles on this leave it at "it's a rolling window, space your usage." This page shows you the field, the file, the formatter, and the exact two-curl path to read your own cliff timestamp.
Why Tuesday, specifically
The pattern people describe is the same one. They sit down Sunday afternoon or Monday morning to clear backlog. Most of their week of Claude work happens in the first 48 hours of the cycle. By Tuesday afternoon, they are 60 to 90 percent into the seven-day bucket and their cliff lands later that day or Wednesday morning. The natural reaction is to assume the weekly allowance shrunk. It did not. The allowance is the same; the clock just started Sunday and is now 48 hours deep into a 168-hour window.
The cliff is not aligned to a calendar boundary. It is aligned to the message that started your cycle. Two engineers with identical Max plans, identical workloads, but different cycle starts will hit the wall on different days. The only way to know your specific cliff is to read seven_day.resets_at from the server.
One message, one 168-hour clock, one reset timestamp
Where resets_at comes from
Each bucket carries its own resets_at. The seven-day bucket is the one that lands you on Tuesday. The five-hour bucket is the one that can take you out within an afternoon if you are in a heavy stretch.
Anchor fact: every bucket has 0 resets_at field
The Rust struct ClaudeMeter deserializes the /usage response into is short. Two fields per bucket. One is the utilization. The other is the cliff timestamp. The whole concept of a Claude weekly limit lives in those two fields, repeated seven times.
The 11-line countdown
The popup converts the ISO timestamp into a human-readable countdown with one function. Subtract now, pick the unit. Under one hour shows minutes. Under 48 hours shows hours. Otherwise days. The thresholds are the load-bearing part: hours up to 47 keeps the resolution useful when you are close to the cliff, days for anything further so a three-day countdown does not show as a noisy 73h.
That string is then concatenated into the row label. The popup row is built one bucket at a time, and the label always reads as ${label} · ${resets} when resets_at is present. So the seven-day row literally reads 7-day · 4d when you are four days from your cliff.
What ClaudeMeter does with the field
Six concrete behaviors that all hang off the same resets_at field.
Reads server-side resets_at
GET /api/organizations/{org_uuid}/usage with your existing session cookie. Each Window in the response has resets_at. That field is the cliff timestamp.
Live countdown, not a snapshot
fmtResets converts the ISO string into 12m, 23h, or 5d. Polled every 60 seconds. The countdown drifts as the rolling window rolls.
All seven buckets countdown separately
five_hour, seven_day, seven_day_sonnet, seven_day_opus, seven_day_oauth_apps, seven_day_omelette, seven_day_cowork. Each renders as label · countdown.
Badge shows the worst slice
The toolbar icon badge displays the highest five_hour percent across all logged-in orgs. You see the cliff coming without opening the popup.
Works while you are away from claude.ai
chrome.alarms.create('refresh', { periodInMinutes: 1 }) keeps the service worker polling whether or not the Settings page is open. The countdown stays current.
No cookie paste
credentials: 'include' on the fetch reuses your existing claude.ai session. The Rust menu bar app (Route B) reads Chrome Safe Storage if you prefer no extension.
What the popup does every minute
alarm to render, in eight steps
fmtResets is the only piece of UI logic between the JSON and the row label. Everything else is fetch and render.
Reproduce your own cliff in two curl calls
Paste your claude.ai cookie into $COOKIE. Hit account, then hit usage. The second response has seven_day.resets_at. That is your cliff. No installation, no extension, no menu bar.
Read your reset timestamp in five steps
Open DevTools on claude.ai/settings/usage
Sign in to claude.ai. Open the Settings then Usage page. Open DevTools, switch to the Network tab, filter for usage. The page fires a request to /api/organizations/{org_uuid}/usage when it loads.
Inspect the response JSON
Click the request, switch to the Response tab. You will see seven fields shaped like { utilization, resets_at }. The seven_day field is your weekly bucket.
Copy seven_day.resets_at
It is an ISO-8601 string in UTC, for example 2026-04-30T14:22:00Z. That is the moment the oldest still-counted message will age out, and your weekly utilization will tick down accordingly.
Subtract now from resets_at
If resets_at is more than 48 hours away, you are early in the cycle. If it is less than 24 hours and your utilization is above 80 percent, the Tuesday cliff is real and arriving. The math is exactly what fmtResets does in 11 lines.
Or skip the manual step
Install the ClaudeMeter extension. The popup row labels render as 7-day · 4d automatically. No copy-paste, no reload-the-Settings-page-every-hour habit.
Which tools surface resets_at?
The cliff timestamp is a server-side field. A tool that reads only local logs cannot show it without adding a session-cookie path and an HTTP client to the /usage endpoint.
| Feature | Local-log trackers (ccusage, Claude-Code-Usage-Monitor) | ClaudeMeter |
|---|---|---|
| Shows resets_at as a countdown | No. Local logs do not contain this field. | Yes. fmtResets renders 12m / 23h / 5d. |
| Knows your window started at first message | Assumes a fixed weekly boundary or the time of the last command. | Yes. resets_at reflects the rolling 168-hour clock. |
| Updates the countdown live | No. Recomputes only when you run a Claude Code command. | Yes. 60-second poll keeps the countdown current. |
| Renders 7d Sonnet and 7d Opus separately | No. Single global token estimate. | Yes. Each per-model bucket has its own resets_at. |
| Shows the cliff in the browser toolbar | No. CLI only. | Yes. Badge text plus popup. |
| Open source | Most are. ClaudeMeter is too. | Yes. MIT. |
Five wrong moves when the Tuesday cliff lands
Each is something a reasonable engineer does and then loses an afternoon to. None of them require any new product, only reading the timestamp the server already gives you.
Avoid these
- Assuming the weekly cycle starts Sunday midnight or your billing day. It starts at your first message of the cycle.
- Watching only the percent bar on Settings. Without resets_at the bar tells you nothing about when you can keep going.
- Treating ccusage's 'weekly tokens' total as a quota predictor. Tokens are not what gets rate-limited; the server's per-bucket utilization is, and that bucket has a clock.
- Reloading claude.ai/settings/usage every hour to read the timestamp by hand. The endpoint serves the same data; poll it instead.
- Buying Max 20x to push the cliff later. More capacity does not move the clock; only restarting your cycle later in the week does.
Honest caveats
The endpoint is undocumented. Anthropic can rename or drop resets_at without notice. ClaudeMeter types it as Option<DateTime<Utc>> so a missing or renamed field surfaces as a parse error rather than a silently empty countdown. The 168-hour interval is what we have observed across months of polling; it can change on any release. And resets_at drifts in real time as the rolling window rolls. If you snapshot it and then check back six hours later, the value will not be six hours smaller; it is the moment the next-oldest still-counted message will age out, which itself moves with usage.
See your countdown live
ClaudeMeter is free, MIT-licensed, and uses your existing claude.ai session through a browser extension. Your popup row reads 7-day · 4d within a minute of install.
Want help mapping your cycle?
Send us 48 hours of /usage samples. We will mark your real cliff on a chart in 15 minutes.
Frequently asked questions
Why does my Claude weekly limit hit by Tuesday when the week just started?
Because the seven-day bucket is not aligned to a calendar week. It is a rolling 168-hour window keyed off the first message you sent in this cycle. If you started a heavy session on Sunday afternoon, your seven_day window resets the following Sunday afternoon, not Sunday midnight. By Tuesday you are roughly 40 hours into a 168-hour window, and you have probably already burned 60 to 90 percent of the bucket. The cliff is on Tuesday because the clock started Sunday, not because the limit shrunk.
How do I find the exact timestamp my weekly window resets?
Pull GET /api/organizations/{org_uuid}/usage with your claude.ai cookies. The response is a JSON with a seven_day field; that field has a resets_at value that is an ISO-8601 UTC timestamp. That is your cliff to the second. ClaudeMeter's popup converts it for you and renders the row label as something like 7-day · 4d so you see your countdown at a glance. Local-log tools like ccusage and Claude-Code-Usage-Monitor cannot show you this because resets_at lives only in the JSON the server returns, never in ~/.claude/projects/*.jsonl.
Where in ClaudeMeter's source is the reset countdown actually computed?
Two files. The Rust struct that types the field is in src/models.rs lines 3 through 7: pub struct Window { utilization: f64, resets_at: Option<chrono::DateTime<chrono::Utc>> }. The countdown formatter is in extension/popup.js lines 17 through 27, the fmtResets function, which converts the ISO timestamp into 12m, 23h, or 5d depending on how far away it is. The popup row label is built in lines 29 through 40 and renders as `${label} · ${resets}`. So when the field is missing the row falls back to just the label; when it is present you see the countdown.
Does the seven-day window reset all at once or is it actually rolling?
It rolls. Each bucket has its own resets_at. As old usage falls out of the trailing 168 hours, the utilization number ticks down in real time, and resets_at points at the moment the oldest still-counted message will fall off. This means the cliff date moves as you keep using the product. ClaudeMeter polls every 60 seconds, so resets_at is current to the minute.
Why don't ccusage or Claude-Code-Usage-Monitor show resets_at?
Because they read ~/.claude/projects/*.jsonl files locally and count tokens. Those files have your sent and received messages but no field for the server's view of the rolling window. resets_at is computed by Anthropic's backend. The only place it surfaces on the client is the JSON response from /api/organizations/{org}/usage, which neither tool fetches. To make them show resets_at you would need to add a session cookie path, an HTTP client, and a parser for the /usage payload.
Can I see resets_at without installing ClaudeMeter?
Yes. Open claude.ai, log in, open DevTools, go to Application then Cookies, copy your sessionKey and any cookie whose name starts with cf_ or __secure-. Hit GET https://claude.ai/api/organizations/{your_org_uuid}/usage with those cookies and a Referer of https://claude.ai/settings/usage. The response has seven Window-shaped fields. Each one has a resets_at. Pipe through jq '.seven_day.resets_at' to print yours.
How does ClaudeMeter convert the ISO timestamp into 4d or 23h?
fmtResets in extension/popup.js does the math. It subtracts now from the parsed timestamp, then picks the unit: under one hour it shows minutes, under 48 hours it shows hours, otherwise days. The thresholds are deliberate. Hours up to 47 keeps the resolution useful when you are close to the cliff; days for anything further so you do not see a noisy 73h that just means three days. The function lives at lines 17 through 27 and is 11 lines.
Why does the seven-day window start at first message, not at billing day?
Because Anthropic implements quotas as rate-limit windows, not as calendar buckets. A 168-hour window is the standard rolling implementation. Every message ages out 168 hours after it was sent. There is no aggregation at midnight Sunday. The billing cycle is a separate concept from the rate-limit window; your invoice may reset on day-of-month, but the seven-day quota window resets per message. This is also why heavy sessions early in your cycle hit the wall earlier in the next cycle.
What does ClaudeMeter show besides the seven-day countdown?
The popup renders a row per bucket. five-hour, 7-day, 7d Sonnet, 7d Opus. Each row has the label plus countdown, a horizontal bar showing utilization, and the percent. Rows turn amber at 80 percent and red at 100. The icon badge in your browser toolbar shows the worst five_hour percentage so you do not need to open the popup to see if you are about to hit a cliff. The Rust menu-bar app (Route B) prints the same data in the macOS menu bar.
Does upgrading to Max 20x change when my Tuesday cliff lands?
It changes how much you can do before you hit the cliff, not when the cliff is. A bigger seven-day allowance means you can sustain more weekly work, but the rolling 168-hour clock still starts at your first message of the cycle. If your usage pattern is the same, your reset timestamp moves in lockstep. Same Tuesday afternoon cliff, just at a higher absolute total. If your goal is to push the cliff later in the week, you have to push the start of the cycle later in the week, not just buy more capacity.
Keep reading
What a silent-tightening tracker actually needs
Six concrete capabilities. Reads the server endpoint, polls every 60 seconds, watches all seven buckets, normalizes the 0-1 vs 0-100 scale, logs raw JSON, runs in the background.
The rolling cap is seven windows, not one
Anthropic publishes two bars on the Settings page. The endpoint returns seven. Here is every bucket with its field name and reset semantics.
ClaudeMeter vs ccusage
One reads local tokens. One reads the server quota Anthropic enforces. They answer different questions.