[FEATURE] Configurable threshold or opt-out for the recurring weekly-limit usage warning

Status Open
Reported on v2.1.197
Maintainer reply None cached
Activity 3 comments · opened Jul 1, 2026

Problem

Once weekly utilization crosses 75%, Claude Code shows a recurring "You've used NN% of your weekly limit - resets in Xd" warning (VS Code extension banner and CLI). For heavy users who routinely spend the last quarter of the window above 75%, this means days of every week with a permanent warning that carries no new information - we already know we are past 75%, and /usage exists for on-demand checks. It pulls attention on every turn while working and is a real productivity drag.

What I checked (as of 2026-07-01)

  • No related key in the settings.json schema and no environment variable in the docs (settings.md, env-vars.md).
  • The VS Code extension contributes no setting for this (checked contributes.configuration in the extension's package.json, v2.1.197).
  • In the webview bundle, the banner renders whenever the rate-limit status is not "allowed" - there is no client-side threshold or config gate, so the 75% flip appears to be server-driven.
  • Prior requests were closed without shipping: #1798 (not planned), #17431 (autoclosed).

Request

Any one of these would solve it:

  1. A setting or env var to raise the warning display threshold (e.g. show only at >= 95%), or
  2. A toggle to suppress non-blocking usage warnings entirely (keeping hard "You've hit your limit" errors), or
  3. Making the banner dismissible per rate-limit window (dismiss once, stays hidden until the window resets or the status escalates).

Environment

  • Claude Code VS Code extension 2.1.197 (win32-x64), native CLI 2.1.153
  • Windows 11 Pro
  • Claude subscription with weekly limits

View original on GitHub ↗

3 Comments

Komunikuji · 28 days ago

Same need here, and for both windows -- weekly and session. The session-limit banner behaves the same way, so whatever lands should cover both.

I would very likely set the threshold to 95% as well, and I would value the opt-out just as much.

The reason flexibility matters to me: it is not that the warning is always unwanted. Sometimes I am deliberately pacing myself against the limit and want it in view. Other times I am mid-task and it is pure noise. Being able to switch it off when I do not need it, and to tune where it kicks in when I do, would make a real difference -- a single fixed threshold cannot serve both modes.

+1 on options 1 and 2.

erekola · 20 days ago

Same banner on the Claude desktop app on Windows, so this isn't only the VS Code extension and the CLI. Mine reads "You've used 75% of your weekly limit" with a "Get more usage" link next to it, and the 75% flip you describe matches what I see.

The desktop app adds one thing. The X closes the banner for the current app launch only, so it's back the next time I open the app. I restarted the machine to check whether it was stuck. It came straight back. Your option 3, dismiss once and stay hidden until the window resets, would cover it.

The CTA is the part that annoys me most. I have usage credits with auto-reload on, and credits only apply after the plan's included usage is spent, so they never move the percentage the banner counts. The link sells me the thing that is already sitting on the account. I am not sure whether the desktop banner comes from the same code path as the extension one you looked at.

noranda · 17 days ago

Adding two findings from digging through the shipped bundles, both of which sharpen the case here.

1. The trigger is not a flat 75% flip — it can fire below linear pace

I got the banner at You've used 57% of your weekly limit · resets in 4d. That is behind pace, not ahead of it: 57% of the quota consumed with roughly 57% of the window elapsed.

Worth noting because the client actually has its own burn-rate table, and it would not have fired here. In the CLI bundle (2.1.198), seven_day carries:

{ rateLimitType: "seven_day", claimAbbrev: "7d", windowSeconds: 604800,
  thresholds: [ {utilization: 0.75, timePct: 0.6},
                {utilization: 0.5,  timePct: 0.35},
                {utilization: 0.25, timePct: 0.15} ] }

matched as utilization >= m.utilization && elapsedFraction <= m.timePct. With 4d left of a 7d window, elapsedFraction ≈ 0.43, so: 0.57 ≥ 0.75 fails; 0.57 ≥ 0.5 passes but 0.43 ≤ 0.35 fails; 0.43 ≤ 0.15 fails. No rule matches.

So this banner came from the other path — anthropic-ratelimit-unified-7d-surpassed-threshold, set server-side, which the client renders unconditionally with no threshold of its own:

for (let [n, r] of Object.entries(oSp)) {
  let o = e.get(`anthropic-ratelimit-unified-${n}-surpassed-threshold`);
  if (o !== null) { /* ... */ return { status: "allowed_warning", rateLimitType: r, utilization: a, /* ... */ } }
}

That reframes the ask slightly: it is not only that 75% is too aggressive a cut-off, it is that the server-side threshold can fire well below linear pace, and the client has no floor of its own to fall back on. A client-side minimum (option 1 in the original post) would fix this class of case even without a server change.

2. Dismissal is not just non-persistent — it is actively cleared

@erekola's "the X closes the banner for the current app launch only" is the mild version of this. On my setup the banner returns within seconds of dismissing, in the same session, without a reload. The webview handler explains it:

else if (e.type === "rate_limit_event") {
  let i = e.rate_limit_info, n = `${i.status}:${i.rateLimitType ?? ""}`;
  this.currentRateLimitKey = n;
  if (i.status === "allowed") { this.rateLimitWarning.value = null; this.dismissedRateLimitKey = null }
  else if (n !== this.dismissedRateLimitKey) this.rateLimitWarning.value = Klt(i)

Dismissal records dismissedRateLimitKey = "${status}:${rateLimitType}", but the allowed branch clears it unconditionally — with no regard for which rateLimitType that particular allowed event refers to.

A rate_limit_event is emitted per API response, and status falls back to "allowed" whenever that response's headers carry no surpassed-threshold marker (uSp returns null → S = "allowed"). Since the marker is not present on every response — background calls, subagents, and other buckets all produce their own events — a dismissed allowed_warning:seven_day gets un-dismissed by the very next unmarked response, and the following marked response re-renders the banner. dismissedRateLimitKey is also a plain instance field rather than persisted state, so any webview reload loses it too.

This makes option 3 (dismiss-per-window) cheaper than it might look: scoping that reset to the matching rateLimitType, and persisting the key, gets most of the way there without any server-side change.

I have filed the dismissal behaviour separately as a bug, since a dismiss control that does not hold is arguably distinct from the threshold/opt-out request in this thread.

Environment: VS Code extension 2.1.231 (darwin-arm64), CLI 2.1.198, macOS 15.5.