Weekly quota pool: one −14% step between windows, then partial rebound (Max 20x) — earlier −43.5% figure retracted

Status Open
Reported on v2.1.237
Maintainer reply None cached
Activity 3 comments · opened Aug 20, 2026

Summary

Over three consecutive weekly windows on Max 20x, the size of the weekly quota pool — measured by reconciling local transcript token counts against the /usage panel percentages — dropped by 20.8%, then a further 28.7%, for a cumulative −43.5%.

All three windows sat entirely inside the same +50% weekly limits promo (running since May 13, extended to Aug 31), so the promotion cancels out of the comparison. I have not found a policy change that accounts for the decline.

Data

Pool size expressed in weighted input-token units (see Method):

| Window | Promo | Fable sub-pool | Total pool | Change |
|---|---|---:|---:|---:|
| Aug 06 – Aug 13 | +50% active | 115.9M | 231.7M | — |
| Aug 13 – Aug 20 | +50% active | 91.7M | 183.5M | −20.8% |
| Aug 20 – (current) | +50% active | 65.4M | 130.8M | −28.7% |

Underlying Fable-5 measurements:

| Window | Calls | cache_write 5m | cache_write 1h | cache_read | output | Weighted |
|---|---:|---:|---:|---:|---:|---:|
| Aug 06 – Aug 13 | 2,465 | 7,369,523 | 12,259,493 | 679,163,543 | 2,843,308 | 115.87M |
| Aug 13 → Aug 18 05:21 | 2,026 | 802,463 | 9,550,785 | 558,673,155 | 2,419,429 | 88.07M |
| Aug 20 → now | 54 | 0 | 234,069 | 16,367,280 | 99,954 | 2.62M |

Method

  1. Parse ~/.claude/**/*.jsonl for message.usage objects.
  2. Deduplicate by message.idusage is repeated once per assistant content block.
  3. Take output_tokens as the max within each message.id. It varies across records of the same call (observed [5066, 5066, 5066, 5066, 2] and [2, 544]), so both first-record and last-record selection are wrong for some calls.
  4. Weight the four buckets into input-token units using published API cache multipliers: fresh , cache_write 1.25× (5m TTL) / (1h TTL), cache_read 0.1×, output .
  5. Divide by the Current week (Fable) percentage from /usage to get the Fable sub-pool; multiply by 2 for the total pool, since the Fable sub-quota is half the account quota.

Why I trust the method

In the Aug 06 – Aug 13 window, the Fable sub-quota was exhausted first (last Fable call at hour 47) and the account-wide quota later (last Opus/Sonnet call at hour 104). Because the Fable sub-quota is 50% of the account quota, that terminal state forces

total consumption / Fable consumption = 2.000 exactly

Measured: 1.9943 — 0.29% error. This is not a fitted parameter; it is pinned by two independent facts (the 50% sub-quota split and the exhaustion ordering).

Second, independent cross-check: that window's total pool works out to $2,317 at list API prices, against $2,310.74 of measured all-model consumption in the same window — 0.3% apart, as it must be if both quotas were exhausted.

Reliability of each point

  • Aug 06 window — strongest. The quota was actually exhausted, so the pool is measured, not inferred.
  • Aug 13 window — 96% reading; the ±0.5% rounding contributes only ±0.5% relative error. Independent path: the full window's Fable consumption was 94.74M, which if it also ended exhausted puts the pool within 3% of the 91.7M inferred from the reading.
  • Aug 20 window — weakest. A 4% reading with ±0.5% rounding spreads the total pool over 116.4M–149.7M. Even at the optimistic end it is 18% below the previous window; at the pessimistic end, 37%.

A hypothesis I am retracting

I previously argued (in #81234) that cache_read is debited against the subscription quota at full price rather than the published 0.1×, producing 4–6× metering inflation. My own data does not support this. Under that assumption the ratio above would be 1.777, not the measured 1.9943. Whatever is happening, cache-read discounting is not it.

Questions

  1. All three windows had identical promo conditions. What accounts for two consecutive double-digit reductions in pool size?
  2. Is the weekly pool a fixed quantity per plan, or is it adjusted per-account — e.g. based on recent usage history?

Environment

  • Claude Code 2.1.237, native install, Linux
  • Max 20x, Google Play billing
  • I use Claude Code almost exclusively; very little of my usage originates from claude.ai web, desktop, or mobile. Local transcripts therefore cover nearly all of my consumption, and any uncaptured usage would only make the reported pools an underestimate.

View original on GitHub ↗

3 Comments

aguynamedryan · 2 days ago

Second dataset, different account, same direction.

Independent reconstruction using the same method described in the issue, on a
different account. Three readings, one of which is a hard refusal rather than a
rounded /usage glance.

Readings

| observed | source | reported | burn to that instant (weighted) | implied pool |
|---|---|---:|---:|---:|
| 2026-08-21 09:13 PDT | user-noted /usage | 82% | 770 M | 940 M |
| 2026-08-22 12:23 PDT | REFUSAL event | 100% | 908 M | 908 M |
| 2026-08-27 09:31 PDT | /usage | 43% | 345 M | 801 M |

-12% between the refusal and five days later, with the +50% promo
active throughout both windows.

It is not an artifact of the weighting

| weighting | 08-22 pool | 08-27 pool | change |
|---|---:|---:|---:|
| as in #88352 (1x / 1.25x 5m / 2x 1h / 0.1x / 5x) + per-model price | 908 M | 801 M | -12% |
| same, without per-model price scaling | 998 M | 871 M | -13% |
| flat 1.25x cache-write (no TTL split) | 872 M | 753 M | -14% |
| output weighted 1x instead of 5x | 810 M | 742 M | -8% |
| raw tokens, no weighting at all | 7,080 M | 6,182 M | -13% |

The decline holds under every scheme including no weighting at all, so it is not
a consequence of assuming Anthropic's cost model. In raw terms: the same account
burned ~13% fewer tokens per percentage point of weekly quota five days apart.

Method

As described in #88352, arrived at independently before reading it:

  1. Parse ~/.claude/projects/**/*.jsonl for assistant records carrying message.usage.
  2. Deduplicate by requestId — one API call spans several transcript lines.
  3. Take output_tokens as the MAX within a request id. It is a running counter that

only reaches its final value on the last line; taking the first drops 27% of all
output tokens corpus-wide (up to 47% in one week).

  1. Sum across all machines on the account. Window boundary is Mon 16:00 PT, confirmed

by the refusal message naming its own reset time.

  1. Divide burn-to-that-instant by the reported percentage.

What I checked before posting this

  • Weighting: the decline holds under every scheme above including no weighting at all,

so it is not an artifact of assuming a cost model.

  • Untracked clients: every billed assistant turn in the corpus carries

entrypoint: cli — 36,022 of them since 2026-08-01, with no web, desktop or mobile
entrypoint anywhere. The account holder also confirms near-zero use of those clients. This
is the caveat I most expected to be fatal and it is not present here.

  • Missing machines: all machines on the account were enumerated; one further host exists

but has no ~/.claude/projects at all.

  • Retention: cleanupPeriodDays is 10000 on all three contributing machines, so no

window has been silently pruned.

  • Dedup stability: raw transcript lines per request are 1.99–2.37 across the windows, so

the deduplication is not behaving differently between the two readings being compared.

  • Window boundary: confirmed by the refusal message naming its own reset time.

Caveats, stated plainly

  • Three readings is a short series, and two are integer-rounded percentages. Rounding

moves each pool figure by a few percent; it cannot produce 12%.

  • The 100% row is the reliable one — a refusal event, not a glance. It is also

independently recorded on a second machine on the same account seven seconds later,
each rendering the reset in its own local timezone ("resets Aug 24, 4pm
America/Los_Angeles" on one, "resets Aug 24 at 5pm America/Denver" on the other). Two
machines, two timezones, one account-wide limit, same instant.

  • The reading times are when the percentage was written down; if the panel was consulted

earlier, burn was lower and the implied pool is smaller still. So the final figure is an
upper bound.

  • The pool is derived, not published. If the metering has a dimension not visible in

local transcripts, this method cannot see it. That is a limit of the method, not of this
dataset, and it applies equally to the original report.

  • One account. That is precisely why a second dataset seemed worth adding.

Happy to share the extraction script if useful.

zhuran24 · 2 days ago

Update after the Aug 20 window closed — correction

Complete Aug 20–27 data, using the method in the issue:

| Scope | Calls | fresh | write 5m | write 1h | cache read | output (max/id) | Weighted | List-price |
|---|---:|---:|---:|---:|---:|---:|---:|---:|
| Fable | 1,774 | 526,338 | 893,441 | 10,439,034 | 492,107,505 | 2,480,530 | 84.13M | $841.35 |
| Other Anthropic | 7,296 | 1,732,603 | 31,678,356 | 17,219,856 | 1,080,653,568 | 11,948,433 | 243.58M | $1,209.99 |
| Total | 9,070 | 2,258,941 | 32,571,797 | 27,658,890 | 1,572,761,073 | 14,428,963 | 327.71M | $2,051.34 |

The last non-Fable call was Aug 24 17:37 EDT; the last Fable call was 17:42 EDT. Then all Anthropic models stopped until reset. This is an account-wide terminal state, not a separately observed Fable exhaustion.

I therefore retract the third point’s −28.7% and the headline’s cumulative −43.5%. My 4% reading was too early to extrapolate, and multiplying it by 25 and then by 2 assumed a Fable half-pool that this window never independently measured.

Across the three complete windows, actual all-model consumption was:

  • unpriced weighted units: 379.77M → 313.82M → 327.71M (−17.4%, then +4.4%);
  • list-price: $2,310.74 → $1,984.97 → $2,051.34 (−14.1%, then +3.3%).

The Aug 06 2.000-ratio check remains valid because Fable stopped first (hour 47) and the account later (hour 104). Aug 20 lacks that ordering, so its Fable sub-pool is unmeasurable. The complete evidence shows a dip and partial rebound, not three consecutive reductions. I am correcting the conclusion accordingly.

zhuran24 · 2 days ago

@aguynamedryan Thanks — yes, please share the extraction script. A second-account implementation will be useful, especially for comparing requestId versus message.id deduplication and multi-machine merging.

My completed Aug 20 window changed my own conclusion. Fable and the other models stopped within six minutes at the account-wide limit, so the Fable half-pool was not independently measured; the early 4% extrapolation was invalid. My corrected complete-window series shows a dip followed by a partial rebound, not three consecutive reductions, and I no longer stand by the −43.5% headline.