●BILLING — 1 day to the Jun 15 change: Agent SDK, headless runs, GitHub Actions, and third-party agents move to separate monthly credits ($20/$100/$200) metered at full API rates, no rollover●FABLE5 — Claude Fable 5, a Mythos-class model billed as Anthropic's most capable generally available release, is usable in Claude Code v2.1.170+ (launched Jun 9)●SUBAGENTS — Claude Code sub-agents can now spawn their own sub-agents, with smarter model and region handling●ENTERPRISE — Custom roles gain admin permissions, letting members reach billing and privacy settings without Owner access●PLUGINS — New plugin search plus better Chrome, VSCode, and terminal workflows; session, memory, and permission bugs fixed●UI — New setting disables mouse-wheel scroll acceleration in fullscreen; the /model picker now shows model families correctly●BILLING — 1 day to the Jun 15 change: Agent SDK, headless runs, GitHub Actions, and third-party agents move to separate monthly credits ($20/$100/$200) metered at full API rates, no rollover●FABLE5 — Claude Fable 5, a Mythos-class model billed as Anthropic's most capable generally available release, is usable in Claude Code v2.1.170+ (launched Jun 9)●SUBAGENTS — Claude Code sub-agents can now spawn their own sub-agents, with smarter model and region handling●ENTERPRISE — Custom roles gain admin permissions, letting members reach billing and privacy settings without Owner access●PLUGINS — New plugin search plus better Chrome, VSCode, and terminal workflows; session, memory, and permission bugs fixed●UI — New setting disables mouse-wheel scroll acceleration in fullscreen; the /model picker now shows model families correctly
Pacing Non-Rollover Monthly Credits: A Burn-Rate Scheduler That Avoids Both Early Exhaustion and Wasted Balance
Non-rollover monthly credits punish you for spending too fast and for spending too slow. Here is the design of a scheduler that derives a daily burn rate from remaining balance and days left, throttles headless runs automatically, and the real numbers from running it on a personal automation setup.
I stopped mid-sip when the start-of-month summary printed. The previous billing cycle, I had left 18% of my reserved credit completely unused as the month rolled over.
If it had carried over, I would not have cared much. But headless runs after the June 15 change do not roll over. Whatever you do not spend vanishes the instant the month flips. Spend too eagerly in the first half, and the back half lands you on full API-rate metered billing.
Running several sites on automation as a personal developer, this asymmetry — losing money whether you overspend or underspend — wears on you quietly. This article shares the design of a burn-rate pacing scheduler that recomputes the "speed you're allowed to spend at" every single day, from remaining balance and the calendar.
The morning I found 18% sitting unused
What I run is a set of scheduled headless tasks — non-interactive claude -p style executions, staggered across the day, several per day.
The trouble was that token consumption per task is anything but uniform. A short integrity check finishes in a few thousand tokens; a long-form generation task can reach hundreds of thousands in a single run.
Early in the month I'd feel I had room and run generously; as month-end neared I'd unconsciously hit the brakes, afraid of running short. Running on human intuition is exactly what produced that 18% of unused balance. I had erred so far toward safety that I never put the reserved budget to work.
With non-rollover monthly credits, that gut-feel operation becomes a direct loss. A balance that is designed to disappear has to be spent deliberately — but without starving out. That calls for numbers derived from balance and date, not a feeling.
The two-sided loss that non-rollover credit creates
First, the constraints. After June 15, the Agent SDK, headless claude -p, GitHub Actions, and third-party agents moved to a separate monthly credit pool, distinct from subscription usage limits. The pool is $20 (Pro) / $100 (Max 5x) / $200 (Max 20x) depending on plan, overage bills at the full API rate, and — critically — it does not roll over.
That non-rollover rule produces a loss in two directions.
One is early exhaustion. If your burn rate runs too hot in the first half, every run after the pool empties flows to metered billing. A cost you thought you had fixed creeps toward open-ended by month-end.
The other is leftover waste. Lean too far toward safety and the balance evaporates unused at month-end. That's the one I hit. 18% of a $200 pool — about $36 — thrown away every single month.
The ideal is a steady pace that lands the balance near zero exactly at month-end. But real tasks vary in consumption, so a fixed schedule can never match it. That's precisely why you need a mechanism that measures the pace and nudges it daily.
✦
Thank you for reading this far.
Continue Reading
What follows includes implementation code, benchmarks, and practical content we hope you'll find useful. This site runs without ads — server and development costs are supported entirely by members like you. If it's been helpful, we'd be truly grateful for your support.
WHAT YOU'LL LEARN
✦A pacing formula that derives today's spend ceiling from remaining credit and days left, with the complete TypeScript implementation
✦Pre-estimating the token cost of each headless run so the queue stops before it overshoots — which cut my end-of-month waste from 18% to 2%
✦Decision rules for using up a non-rollover, full-API-rate credit pool without starving high-priority tasks
Secure payment via Stripe · Cancel anytime
✦
Unlock This Article
Get full access to the rest of this article. Buy once, read anytime. This site is ad-free — your support goes directly toward keeping it running.
The idea is simple. Each morning, check three things:
Remaining credit (what's left to spend this month)
Days left until month-end
How much you've already spent today
The allowed daily spend is then "remaining credit ÷ days left." That's today's baseline burn rate. Once today's actual spend reaches that baseline, you halt discretionary runs for the day.
The key is to recompute the baseline daily. If yesterday came in light, the surplus rolls into today's remaining balance and the pace automatically ticks up. If yesterday ran hot, today's baseline automatically drops to compensate. A balance-based dynamic daily allowance, not a fixed per-day split — that was the trick.
// burn-rate.ts — derive today's allowed spend from balance and days leftexport interface CreditState { monthlyCredit: number; // pool reserved for the month (USD), e.g. 200 spentThisMonth: number; // actual spend so far this month (USD) spentToday: number; // actual spend so far today (USD) now: Date;}export interface PaceDecision { remaining: number; // remaining credit daysLeft: number; // days left including today dailyBudget: number; // today's spend ceiling todayHeadroom: number; // spend still available today canRun: boolean; // okay to run more discretionary work?}function daysLeftInMonth(now: Date): number { const y = now.getUTCFullYear(); const m = now.getUTCMonth(); const lastDay = new Date(Date.UTC(y, m + 1, 0)).getUTCDate(); return lastDay - now.getUTCDate() + 1; // include today}export function decidePace(s: CreditState): PaceDecision { const remaining = Math.max(0, s.monthlyCredit - s.spentThisMonth); const daysLeft = daysLeftInMonth(s.now); // balance-based dynamic daily split; yesterday's over/under is absorbed const dailyBudget = remaining / daysLeft; const todayHeadroom = dailyBudget - s.spentToday; return { remaining, daysLeft, dailyBudget, todayHeadroom, canRun: todayHeadroom > 0 };}
Setting monthlyCredit slightly below the full pool further curbs the risk of spilling into metered billing at month-end. Against a $200 pool I use $190 as the baseline. The remaining $10 is a safety margin reserved for tasks I absolutely cannot drop.
Estimating tokens before the run, and stopping the queue
Even with a burn-rate baseline, deciding to stop after spending is too late. "You went over budget" after a long generation has already run means the overage is already metered.
So before pulling the next task off the queue, estimate its cost up front. If the estimate exceeds today's headroom, defer it to a later day.
Using the median of past measurements per task type proved practical. Median rather than mean, so an occasional outlier mega-run doesn't drag the baseline around.
// estimate.ts — estimate cost up front, per task typetype TaskKind = "integrity" | "shortgen" | "longgen" | "review";// median of past measurements (input/output tokens); update as you operateconst MEDIAN_TOKENS: Record<TaskKind, { input: number; output: number }> = { integrity: { input: 8_000, output: 1_500 }, shortgen: { input: 40_000, output: 12_000 }, longgen: { input: 180_000, output: 60_000 }, review: { input: 90_000, output: 8_000 },};// full API rate (USD / 1M tokens); update to your contract and modelconst RATE = { input: 3.0, output: 15.0 };export function estimateCost(kind: TaskKind): number { const t = MEDIAN_TOKENS[kind]; return (t.input / 1_000_000) * RATE.input + (t.output / 1_000_000) * RATE.output;}
The estimate is only a median-based approximation. After each run, record actual consumption and update spentToday and spentThisMonth with real numbers. Manage the budget with estimates, reconcile the ledger with actuals. That two-layer approach is what worked under non-rollover operation.
Implementing the pacing scheduler
Now combine the two. Order the queue by priority and, top down, decide each task by whether today's headroom can fit it.
// scheduler.ts — drain the queue using burn rate and pre-estimatesimport { decidePace, CreditState } from "./burn-rate";import { estimateCost } from "./estimate";interface Task { id: string; kind: "integrity" | "shortgen" | "longgen" | "review"; priority: number; // lower is higher priority mustRun?: boolean; // run even if it dips into the safety margin}export function planToday(queue: Task[], credit: CreditState) { const run: Task[] = []; const deferred: Task[] = []; const sorted = [...queue].sort((a, b) => a.priority - b.priority); let spentToday = credit.spentToday; for (const task of sorted) { const pace = decidePace({ ...credit, spentToday }); const cost = estimateCost(task.kind); // top-priority tasks pass as long as balance (incl. margin) remains if (task.mustRun && pace.remaining - cost > 0) { run.push(task); spentToday += cost; continue; } // normal tasks pass only within today's headroom if (pace.canRun && cost <= pace.todayHeadroom) { run.push(task); spentToday += cost; } else { deferred.push(task); } } return { run, deferred, spentToday };}
Only mustRun tasks pass beyond the daily split, as long as monthly balance remains. Tasks like integrity checks or failure detection — the kind whose loss breaks operations — must never be halted for the sake of pacing. I drew a clear line: pacing exists only for discretionary work.
Using up the pool while honoring priority
The awkward part is the month-end remainder. Stop strictly on the daily split and, depending on consumption variance, a small balance lingers at month-end. Leave it unspent and you're back to the same loss.
So for the final few days, I loosen the rule slightly. Once fewer than three days remain, treat remaining (the whole balance) as the day's headroom rather than dailyBudget, and re-pick the deferred tasks in priority order.
// end-of-month sweep: with <3 days left, go spend down the whole balanceexport function endOfMonthSweep(deferred: Task[], pace: { remaining: number; daysLeft: number }) { if (pace.daysLeft > 3) return []; const picked: Task[] = []; let budget = pace.remaining; for (const t of deferred.sort((a, b) => a.priority - b.priority)) { const cost = estimateCost(t.kind); if (cost <= budget) { picked.push(t); budget -= cost; } } return picked;}
Since I added this "end-of-month sweep," waste dropped visibly. Deferred quality-improvement tasks get cleared in a batch at month-end, so the budget that would have been thrown away turns straight into article revisions. Credit that was only going to vanish became results instead.
What measurement taught me that the design could not
There were several gaps between what I assumed at design time and what two months of running actually showed.
First, the median estimates drift unless you update them mid-month. As the subject matter shifts, so does consumption. I now re-derive the medians from recent actuals once a week. Skip it, and the estimates drift from reality and budget control goes soft.
Second, tagging too many tasks mustRun breaks pacing entirely. Out of anxiety I first marked nearly everything essential, and they all ended up eating into the safety margin together. Narrow it to what truly cannot be dropped. That revision is what finally gave the daily split meaning.
Third, time-zone handling. Both days-left and "today's spend" depend on which reference clock you reset on. If your billing cutoff and your log dates disagree, an entire day at the month boundary gets double-counted or missed. I aligned my log dates to the same reference as the billing cutoff, without exception.
In numbers: end-of-month waste moved from 18% to 2%, and overage-driven metered billing went from tens of dollars a month to near zero. Spending the reserved pool fully — neither tossing it nor overflowing it. Unglamorous, but the single most effective improvement under the non-rollover constraint.
If you're going to try this
If you're reconfiguring operations under the same constraint, I'd recommend starting by simply logging the daily "allowed burn rate." Pipe decidePace's output to a log and run a week with a human deciding when to stop. That alone surfaces the shape of your own spending in numbers.
Automating the queue's stop point is plenty for after that shape becomes visible. Rather than aiming for full automation from day one, the order of measure first, then semi-automate, then automate is what made me comfortable trusting a non-rollover pool to the machinery.
I hope it gives those of you juggling multiple headless runs a workable starting point for your own design.
Share
Thank You for Reading
Claude Lab is ad-free, supported entirely by members like you. We publish practical guides daily with implementation code, benchmarks, and production-ready patterns. If you've found it useful, we'd love to have you on board.