[SEV-1] budget.spent() reports 72x under actual consumption - blew through my weekly budget in 4 hours. Escalate cost controls before this hits other users.

Status Open
Reported on v2.1.220
Maintainer reply None cached
Activity 2 comments · opened Aug 1, 2026

Bug Description
Severity

Critical — quota accounting and cost-control failure

Summary

We ran a tested, instrumented pipeline across 36 of 50 agents. That completed 72% of the project while consuming only approximately 3–4% of the weekly Max quota.

The pipeline had already proven that its cost controls worked:

200K token limit per agent
Hard abort checkpoints
Runaway guards
Per-agent spend ledger
Concurrency-aware accounting
Multiple successful production runs

We then reached the weekly utilization limit, waited only a few hours—likely fewer than six—and resumed the same pipeline.

Nothing material changed in the workflow.

The remaining 14 agents then consumed approximately 20% of the weekly quota in about four hours—more than 10 times the expected consumption.

Every agent still reported below the 200K limit.

No budget threshold was exceeded.

No guard fired.

No anomaly appeared in the ledger.

The only indication was the account-level weekly utilization meter after the quota had already been consumed.

Core Bug

Claude Code’s workflow-visible budget accounting did not reflect the consumption being charged against the weekly Max quota.

The pipeline believed every agent was under its 200K ceiling, while the platform was consuming quota at a radically higher rate.

This made every cost control ineffective despite the controls having already been validated across 36 successful runs.

This is not a forecasting error or an untested workload. A previously proven process became more than 10 times as expensive after a short pause, with no observable signal explaining why.

Evidence

Before the pause:

Agents completed: 36 of 50
Project completed: 72%
Weekly quota consumed: approximately 3–4%
Per-agent limit: 200K
Budget violations: none

After resuming:

Agents remaining: 14 of 50
Weekly quota consumed: approximately 20%
Elapsed time: approximately 4 hours
Per-agent limit: 200K
Reported violations: none
Runaway guards fired: none

Post-mortem session accounting showed approximately:

Output tokens: 11.3M
Cache-read tokens: 819.5M
Cache-write tokens: 50.6M

The exposed budget controls appeared to track output-token usage, while weekly quota consumption was dominated by token classes the pipeline could not see or constrain.

Suspected Failure Boundary

Something changed between the validated run and the resumed run, potentially involving:

Prompt-cache reuse
Cache expiration and context rewriting
Model or routing behavior
Concurrency handling
Token accounting
The data supplied to budget.spent()

The important fact is that platform-side consumption changed dramatically while workflow-side accounting did not.

Expected Behavior

A 200K hard limit should prevent an agent from consuming materially more than its configured budget.

If weekly quota is calculated using input, output, cache-read, and cache-write consumption, the budgeting interface must measure those same categories.

A previously validated pipeline should not become more than 10 times as expensive without:

Triggering a budget limit
Producing an anomaly warning
Showing an increased live burn rate
Requiring confirmation before proceeding
Exposing which consumption category increased
Actual Behavior

All 14 resumed agents remained below the reported 200K limit, yet together consumed approximately 20% of the weekly Max quota.

Claude Code provided no warning, abort mechanism, or accurate in-process measurement.

Required Fixes
Make budget limits use actual quota consumption, including input, output, cache-read, and cache-write tokens.
Clarify or rename budget.spent() if it measures only output tokens. The current name implies total spend.

Add a quota-based hard stop, for example:

Abort this workflow after consuming 2% of my weekly quota.

Expose a live weekly-quota burn meter during agent and fan-out execution.
Warn before resuming a large or cache-expired session, including an estimate of the initial cache-write cost.
Record model, routing, cache, and accounting changes so a sudden cost regression can be diagnosed.
Impact

A user implemented every available safeguard, validated those safeguards across 72% of a real workload, and then watched the same process consume approximately 20% of a weekly allowance without any control detecting it.

The absence of an accurate budget signal means users currently have no reliable way to prevent this class of runaway quota consumption.

Other Max users may have experienced the same failure without realizing why their weekly allowance disappeared.

Environment Info

  • Platform: linux
  • Terminal: cursor
  • Version: 2.1.220
  • Feedback ID: bc61e23b-a08e-47fa-a8ef-b942bc84d0e3

Errors

[]

View original on GitHub ↗

3 Comments

deemwario · 2 months ago

The pause is almost certainly the cause, and your own post-mortem numbers already show it.

Output 11.3M, cache-write 50.6M, cache-read 819.5M. Output is about 1.3% of the tokens that actually moved. Your per-agent 200K ceiling was measuring that 1.3%, so it was never going to fire no matter how far the run overran. Nothing was broken about the guard — it was watching the wrong quantity.

What the pause did: prompt caches have a short TTL (5 minutes by default, an hour on the extended option). A wait of "fewer than six hours" expires all of them. Before the pause, each agent's stable prefix was a cache read, billed at a small fraction of base input. After it, that identical prefix has to be re-ingested as a cache write — priced above base input — and then read again. Same workflow, same context, same code path, and the per-agent cost steps up by roughly the read-to-write ratio. That is the shape you saw: 36 agents cheap, short pause, remaining 14 at roughly 10x.

It also explains the silence. cache_creation and cache_read are separate token classes from output. If the ledger sums only output — or only what the tool surfaces — then the entire class that changed is invisible to it. No threshold crossed, no anomaly, no guard, right up until the account-level weekly meter catches up.

Two things that would make this observable:

  • Track all four classes separately (input_tokens, output_tokens, cache_creation_input_tokens, cache_read_input_tokens) rather than collapsing to one number. Every API response reports them in its usage block; the failure mode is summing the wrong subset.
  • Treat any resume-after-idle as a cache-cold run and expect the first pass over each agent's context to be charged at write rates. Note the perverse interaction here: a pipeline that pauses because it hit a quota will systematically resume into its most expensive possible configuration. The limiter and the cache actively fight each other.

The general trap, and the reason this class of bug is so quiet: a budget control that runs inside the thing being budgeted can only count what that thing chooses to expose. The number that actually gets billed lives at the API boundary.

deemwario · 2 months ago

One follow-up in case it helps close this out: you can confirm the cache-cold mechanism straight from your own usage data, no new instrumentation. Pull cache_creation_input_tokens for the 14 post-resume agents and compare them against the 36 that ran before the pause. If the post-resume agents show a large cache-creation spike where the earlier ones were almost entirely cache_read_input_tokens, that's the whole story — the stable prefix that was being read at a fraction of base input is being re-written at above base input. Which also sharpens the budget.spent() puzzle: it isn't so much miscounting as summing the wrong classes. Output stayed ~1.3% of the tokens that actually moved the whole time, so an output-based ceiling was always blind to the other ~98.7%. The pause didn't change what it was missing — it changed the price of what it was already missing, as that prefix shifted from cache_read (a fraction of base input) into cache_creation (above base input).

Two mitigations, depending on which cost you'd rather take:

  • Don't let a run idle past the cache TTL. If it has to pause on a quota wall, the cheapest resume is one where the caches never go cold — chunk so no agent's context sits idle longer than the TTL (5 min default, 1 h on the extended option), or checkpoint-and-replay rather than pause-in-place.
  • If a cold resume is unavoidable, price it as one. Re-estimate the first post-resume pass at cache-write rates and size the remaining budget against that, so the resume doesn't silently run at the wrong price.

Happy to compare notes if you end up rebuilding the accounting around the four token classes — from experience it's a sharp edge, and the fix is mostly where you put the counter, not how big the ceiling is.

celikkanat · 1 month ago

This is a very useful failure report, especially the mismatch between the exposed budget signal and the token classes that actually consumed quota.

I'm building LLMCap as a provider-independent enforcement layer that blocks requests before they happen based on project, user, model, and run budgets. Your cache-read/cache-write example exposes an important requirement: a hard cap is only trustworthy if it accounts for the same dimensions the provider actually bills or uses for quota.

Would you be open to a short feedback exchange? In your workflow, would the most useful external control be:

  1. a hard quota/cost stop before each call,
  2. attribution showing which agent/run/token class caused the burn, or
  3. both, with a recoverable pause rather than terminating the session?

Demo, if useful: https://app.llmcap.io/demo

No generic sales pitch -- I'm trying to validate the enforcement boundary against real failures like this one.