The Claude rolling 5-hour reset is N staggered resets, not one
You hit a 429, googled “claude rolling 5 hour reset”, and every page told you to wait 5 hours from your first message. You waited. The bar is still at 60%. This page explains why, with the actual field Anthropic returns and what it means.
Direct answer (verified 2026-05-09)
The rolling 5-hour window does not reset all at once. Each message you send has its own private 5-hour clock; the cost of that one message drops off the bucket exactly 5 hours after you sent it. The resets_at timestamp at claude.ai/settings/usage is when the OLDEST message in the current window will age off, not when utilization returns to 0%. The window is only empty 5 hours after the LAST message you sent. Source: the five_hour object on Anthropic’s internal usage endpoint, verified via ClaudeMeter.
What every “5 hours after your first message” guide gets wrong
Open the first ten guides on this topic and they all say the same thing: “Send your first message at 9am, your reset is at 2pm.” That is true once, on a session with exactly one message. As soon as you send a second prompt, that rule is wrong by design. The cost of message two ages off 5 hours after message two, not 5 hours after message one.
So when a chatty afternoon session has 14 messages spread between 1pm and 5pm, you do not have one reset at 6pm. You have 14 separate age-offs spread between 6pm and 10pm. The bar steps down 14 times. The Settings page can only show you the next step. People who wait for “the reset,” come back at the time the page printed, and find the bar still well above 0% are seeing exactly this behavior. Nothing is broken. The headline number is the next step, not the destination.
The reason every popular guide misses this is that the server only ever returns ONE timestamp per window. There is no list of per-message age-offs in the API. You have to either stare at it for 5 hours, or read the source of a tool that polls it for you, to notice the stair-step pattern. Below is what that staircase actually looks like.
The reset, frame by frame
Three messages, three age-offs. The Settings page (and ClaudeMeter) show you the same payload at each tick. Watch resets_at and utilization move:
Notice that resets_at does not move when you send new messages, because new messages are never the oldest. It only jumps forward when the current oldest message ages off, at which point the next-oldest becomes the new candidate. So you watch the field tick by sometimes-jumping forward, not by smoothly counting down to one moment.
The five steps a single age-off goes through
1. You send a message
The server time-stamps the request when it lands at the rate limiter (not when you started typing). That timestamp gets added to your org's five_hour bucket with whatever cost weight Anthropic computes for that prompt (per-model multiplier, peak-hour multiplier, attachments, tool calls).
2. Utilization climbs by the cost of that one message
Your live utilization is the sum of all message costs whose timestamps are within the last 5 hours. Send a heavier Opus prompt with attachments and the bar jumps further than a quick Sonnet question. Send nothing for an hour and the bar does not move.
3. Each message ages off on its own private 5-hour clock
Five hours after the timestamp on a given message, that message's cost is subtracted from the bucket. Not your whole bucket: just that one message's contribution. The bucket steps DOWN by exactly that much. If three messages happen to age off at nearly the same moment, you see three steps down, not one collapse to 0%.
4. resets_at always points at the next age-off
The server picks the oldest message still in the window and returns its age-off time as resets_at. That is the next moment utilization will drop. After that drop, the next-oldest message becomes the new candidate and resets_at jumps forward to ITS age-off. The Settings page only ever shows you one step ahead.
5. The window is empty 5 hours after the LAST message
Not the first one. The window only returns to 0% utilization when every contributing message has aged off. If you sent prompts continuously between 1pm and 3pm, the bucket only fully empties at 8pm. Most rate-limit explainers report the 5-hours-after-first-message rule, which describes a single-message session and nothing else.
Why the API can only ever show you the NEXT reset
The shape of Anthropic’s response is the constraint. The whole window object is two fields wide:
One float, one optional timestamp. There is no array of pending age-offs, no “fully resets at” field. The server picks the oldest still-counting message and returns its age-off time. That is everything. ClaudeMeter renders that single field verbatim, with no synthesized “final reset”:
If you want to know when you will hit 0%, your only options are to remember the time of your last message and add 5 hours, or to keep polling and watch the staircase. The wire does not give you the full schedule.
The practical takeaway
When the bar says “resets at 6:00pm,” that is the first step down, not the floor. If your session was busy, expect several more steps after 6pm before you are anywhere near 0%. Plan around the time of your LAST heavy prompt, not your first one.
For a refactor that needs hours of headroom, the question to ask is not “when does my window reset.” It is “when did my last big prompt land, and is it more than 5 hours ago.” That is the actual zero-point.
For watching the steps live, the cheapest way is ClaudeMeter. It pulls the same payload claude.ai/settings/usage shows, every 60 seconds, into the macOS menu bar. You see the staircase tick down without having to refresh anything. Free, MIT-licensed, local-only, source on GitHub.
ccusage and Claude-Code-Usage-Monitor cannot show this because they read local JSONL token logs, not the server bucket. Tokens do not un-spend themselves on disk; the server bucket drains as messages age off. Two different ledgers, two different numbers.
The honest caveat
The /api/organizations/{org}/usage endpoint is undocumented. Anthropic could rename resets_at on any release. The behavior described here is what the field does today (verified 2026-05-09). The age-off mechanism itself is inherent to a rolling window and is unlikely to change, but the field name and shape can. ClaudeMeter declares each field as Optional in src/models.rs so a missing or renamed field deserializes to None and the row goes blank instead of crashing. If a name changes, the open-source repo gets a same-day patch.
Trying to plan around the rolling window for an agentic loop?
15 minutes. Bring your worst rate-limited day and we will walk through what the staircase looked like and how to time your next session.
Frequently asked questions
When does the rolling 5-hour window reset?
It does not reset to 0% at one moment. Each message you send has its own 5-hour clock; the cost of that one message drops off exactly 5 hours after you sent it. The resets_at timestamp at claude.ai/settings/usage is the next age-off boundary, which is the oldest message in your current window. Utilization steps down at that boundary by however much that one message cost. The window only fully empties 5 hours after the LAST message you sent.
If resets_at says 6:00pm, will I be at 0% at 6:00pm?
Almost never. resets_at is when one specific contributor (the oldest message still in the window) ages off the bucket. If you sent messages at 1pm, 2pm, and 3pm, resets_at is 6pm and at 6pm only the 1pm message's cost drops out. The 2pm cost still ages out at 7pm; the 3pm cost ages out at 8pm. You are at 0% at 8pm, not 6pm. People who 'wait for the reset' and come back at 6pm to find the bar still at 60% are seeing exactly this.
Where in the API does the 5-hour reset come from?
It comes from one cookie-authenticated GET on claude.ai. Open DevTools on /settings/usage and watch /api/organizations/{org_uuid}/usage fire. The response carries a five_hour object that has exactly two fields: utilization (a float between 0 and 1, sometimes 0 and 100) and resets_at (an ISO 8601 timestamp). One number, one timestamp, per window. There is no per-message age-off list. The server only tells you when the next thing ages off; it does not tell you what comes next.
Why do popular guides say 'window resets 5 hours after your first message'?
Because that is true on a fresh account that sent one message and stopped. It breaks the moment you send a second message. The cost of message two ages off 5 hours after message two, not 5 hours after message one. Most rate-limit explainers stop at the simple case because they were written by someone who tested it once at 9am and reported the 2pm reset. They never reported what 60% to 0% looks like with a chatty session in the middle.
Does the resets_at value move forward as I send new messages?
Sometimes. resets_at always points at the oldest unexpired message in the window. If you send a new message and the oldest message is still inside the 5-hour boundary, resets_at does not move (the new message is now the newest, not the oldest). If you let enough time pass that the oldest message ages out, resets_at jumps forward to the next-oldest message's age-off time. So you watch resets_at by sometimes-stepping forward, not by sliding smoothly.
How do I see the actual remaining time live, instead of refreshing the Settings page?
Install ClaudeMeter (brew install --cask m13v/tap/claude-meter) and load its browser extension. The macOS menu bar pulls the same /api/organizations/{org}/usage payload every 60 seconds and prints '5-hour 58.0% used resets Sat May 9 17:30 (in 2h)' verbatim from the resets_at field. No cookie paste. Numbers match the Settings page exactly because the source is the same endpoint.
Does Claude Code share the rolling 5-hour bucket with claude.ai chat?
Yes on Pro and Max plans. The five_hour bucket on the server tracks the union of your prompts: chat in the browser, prompts inside Claude Code, prompts from Claude Desktop. They all age off on the same per-message clock. This is why ccusage can say 5% used while the server says 95% (ccusage only sees Claude Code; the server sees everything).
Can the rolling 5-hour utilization drop without me doing anything?
Yes, and that is the defining property. If you stop sending messages, the bucket drains as each contribution ages off. Utilization can fall from 90% to 70% to 50% to 0% over the next 5 hours with zero new prompts. That is the rolling part of 'rolling window'. Tools that estimate burn from local token logs cannot show this because tokens do not un-spend themselves on disk.
What about the weekly window, does it reset all at once or rolling?
Same shape, different scale. The seven_day bucket is also a rolling window and also exposes one resets_at field, which is the next-oldest age-off time on a 7-day clock instead of a 5-hour one. Same mental model: it drains in N steps, not one. The Settings page showing 'resets in 3 days' just means the oldest still-counting message ages out in 3 days; you only return to 0% when the LAST message in that 7-day stretch ages out.
Is the 5-hour clock measured from when I started typing or when the request landed?
The server timestamps each request when it hits the rate limiter, not when you started typing. A long-running prompt counts as one timestamp at the moment Anthropic accepted the request. Streaming output does not extend the clock; it is one event. So a 90-second Opus generation that started at 1:30pm ages off at 6:30pm, not 6:32pm.
Keep reading
Burn rate is delta-utilization, not tokens per minute
The right rate to watch on a rolling window is the change in server-side utilization between polls, not the local token total ccusage prints.
The 5-hour server-side wall is three walls, not one
Three stacked conditions can produce a 429 at the 5-hour mark. Where each one lives in the JSON, and why overage_spend_limit has its own clock.
The rolling window cap is seven windows, not one
Anthropic publishes two windows. The internal usage endpoint returns seven utilization buckets, each with its own resets_at and its own throttle.