TAI BUI
Back to curriculum
LearnPython

Action Budgets, Iteration Caps, and Cost Governors

A mid-sized e-commerce agent's monthly LLM cost jumped from $1,200 to $4,800 after its team enabled the "order-tracking" skill. Nothing was wrong with the pricing. The agent had found a new loop and kept spending inside it. Microsoft's Agent Governance Toolkit (April 2, 2026) lists the defenses for this class: per-request `max_tokens`, per-task token and dollar budgets, per-day and per-month caps, iteration caps, tiered model routing, prompt caching, context windowing, human checkpoints on expensive actions, and kill switches on budget breach. Anthropic's Claude Code Agent SDK ships the same primitives under different names. A financial velocity limit, such as cutting access at more than $50 in 10 minutes, catches a loop faster than a monthly cap can.

TIME: ~60 minutesPREREQUISITES: Phase 15 · 10 (Permission modes), Phase 15 · 12 (Durable execution)

Learning Objectives

  • Explain why autonomous agents need a stack of cost limits at different time scales instead of one cap, and name the Denial of Wallet failure.
  • Map each failure mode (runaway loop, slow leak, bad release, legitimate surge) to the layer that catches it first.
  • Configure the Claude Code budget surface: max_turns, max_budget_usd, tool allow and deny lists, and pre-tool hooks.
  • Run the simulator and read its output to see which governor actually stops a polling loop, and tune a velocity limit from an observed spend rate.

The Problem

Autonomous agents spend money on every turn. A chatbot's bad output is a bad reply; an agent's bad loop is a bill. The failure has a name, "Denial of Wallet": the agent keeps reasoning, keeps calling tools, keeps billing, and nothing stops it because nothing was built to.

One number won't fix it. You need a stack of limits at different time scales and granularities: per-request, per-task, per-hour, per-day, per-month. A good stack catches a runaway loop within minutes, a slow leak within hours, and a bad release within a day. It also gives a long-horizon, autonomous agent a budget at all.

The math is trivial. The discipline is where teams fail. Every limit below is named in either the Microsoft Agent Governance Toolkit or the Anthropic Claude Code Agent SDK docs.

Warm-up0/3
1. In a permission-mode ladder, what does moving to a more permissive mode such as auto mode change?Warm-up
Three ascending steps labelled a stricter mode, a middle mode and auto mode, with an arrow pointing toward more permissive. A dashed box on the right asks what changes when you step up, next to a question mark.
Schematic ladder. Mode names other than auto mode are placeholders.
2. What problem does durable execution solve for a long-running agent?Warm-up
A row of five steps where step 4 is marked as a crash and step 5 is dashed. Below it a box named durable execution is followed by the word solves and a question mark.
Schematic with no real durations.
3. A durable runtime automatically retries failed steps after a crash. What cost risk does that create?Warm-up
A box labelled step 3, an arrow to a crash box, then an arrow to a box saying the durable runtime retries failed steps. A question mark asks what cost risk this creates.
Schematic.
Check: The Problem0/1
1. What does "Denial of Wallet" describe?Define
A card showing the term Denial of Wallet, tagged with the lesson section The Problem. Beneath it a line says the context is an autonomous agent run, and a question mark follows the words the term describes.
The term as the lesson names it; its meaning is the question.

The Concept

The cost-governor stack

  1. max_tokens per request. Simple. Prevents any one call from emitting an unbounded completion.
  2. Per-task token budget. Across the whole run, do not exceed N tokens. Hard stop at the cap.
  3. Per-task dollar budget. Same as tokens but in currency. max_budget_usd in Claude Code.
  4. Per-tool call cap. No more than N WebFetch calls, N shell_exec calls, etc.
  5. Iteration cap (max_turns). Total agent loop iterations; prevents infinite reasoning loops.
  6. Per-minute / per-hour / per-day / per-month cap. Rolling windows. Catches leaks at different time scales.
  7. Financial velocity limit. E.g., "if spend exceeds $50 in 10 minutes, cut access." Catches loop-based burn before monthly caps fire.
  8. Tiered model routing. Default to a smaller model; escalate to a larger one only when a classifier judges the task warrants it.
  9. Prompt caching. System prompt and stable context stored in provider cache; token cost of re-sending is near zero.
  10. Context windowing. Compaction / summarization to keep the active context below a threshold; direct token-cost reduction.
  11. HITL checkpoints on expensive actions. Before an action known to be expensive (long tool call, large download, a costly model upgrade), require a human tap.
  12. Kill switch on budget breach. Session aborts when any cap fires. Cap is recorded; requires a separate re-enable path.

Why the stack, not one cap

A monthly cap on its own fires only after the wallet is gone. A per-request cap on its own sees nothing at the session level. Each failure mode lives at a different time scale:

  • Runaway loop (agent stuck in a 5-second retry): caught by velocity limit.
  • Slow leak (agent doing ~2x expected work per task): caught by daily cap.
  • Bad release (new version uses 5x tokens): caught by weekly / monthly cap.
  • Legitimate surge (real demand, not a bug): caught by hour / day cap with clear log.

Claude Code's budget surface

The Claude Code Agent SDK exposes (public docs):

  • max_turns: the iteration cap.
  • max_budget_usd: the dollar cap. The session aborts on breach.
  • allowed_tools / disallowed_tools: tool allowlist and denylist.
  • Hook points before tool use, for custom cost accounting.

Combine these with the permission-mode ladder (Lesson 10). An autoMode session without max_budget_usd is ungoverned autonomy. Anthropic frames Auto Mode as needing budget controls, and the classifier has nothing to do with cost.

EU AI Act, OWASP Agentic Top 10

Microsoft's Agent Governance Toolkit covers the OWASP Agentic Top 10 and the EU AI Act Article 14 (human oversight) requirements. For production in the EU, treat logging and cap enforcement as required.

The observed $1,200 → $4,800 case

The case from the Microsoft docs: an e-commerce agent whose monthly cost quadrupled after a new tool was added. The tool let the agent poll order status during every session, and the setup had no loop detection, no per-tool cap, and no alert on week-over-week growth. The fix was a per-tool cap plus a daily-growth alert. Treat it as a template. Every new tool surface is a new potential loop, so each new tool gets its own cap and its own alert.

Check: The Concept0/23
1. What does max_tokens limit in a cost-governor stack?Define
A JSON request body with fields model, max_tokens set to N and messages, and a question mark asking what max_tokens limits.
Typed example, not captured. Only the field names matter.
2. What does max_turns cap?Define
A loop of three boxes, model reasons, tool call and tool result, with an arrow running back to the start. Below it the setting max_turns is followed by the word caps and a question mark.
Schematic of the agent loop.
3. What happens when a session reaches max_budget_usd?Define
A filled spend bar for a session that has reached a red marker labelled max_budget_usd reached, with an arrow to a dashed box asking what happens next.
Schematic meter, no figures.
4. What is a financial velocity limit?Define
A cumulative spend curve that is shallow at first and then climbs steeply over time, with the words financial velocity limit followed by a question mark.
Illustrative curve; the limit itself is the question.
5. What is tiered model routing?Define
A task box with two arrows to a cheaper smaller model and a costlier larger model, a question mark on the arrows and another beside the words routing rule.
Schematic. The routing rule is the question.
6. What does prompt caching do for an agent's cost?Define
Four request rows, each starting with an identical blue system prompt block followed by an orange block of new turns that grows in each row, and a question about the cost of re-sending the system prompt with prompt caching.
Schematic; block sizes are not to scale.
7. What is a HITL checkpoint in a cost-governor stack?Define
Three neighbouring boxes from the lesson's stack: item 10 and item 12 dashed and unnamed, and item 11 HITL checkpoint with the label what is it, with a question mark under the middle one.
Item 11 as numbered in the lesson; its neighbours are left unnamed.
8. Why is a single monthly cap not enough on its own?Explain
A timeline from the start to the end of a month with one marker near the end labelled by a box reading monthly cap. A question asks whether this one cap is enough on its own.
Schematic of a configuration with a single cap.
9. Why can't a per-request max_tokens stand in for max_turns?Explain
A session drawn as a row of requests one to seven and more, with two settings below, max_tokens and max_turns, each followed by covers and a question mark.
Schematic.
10. What caused the e-commerce agent's monthly cost to go from $1,200 to $4,800?Explain
A bar chart of an e-commerce agent's monthly cost, 1,200 dollars before and 4,800 dollars after, with a question mark asking for the cause of the jump.
Figures from the lesson's e-commerce case.
11. Why does each new tool added to an agent get its own cap and alert?Explain
An agent box with arrows to three tool boxes, tool A, tool B and a dashed box for a new tool, each with cap and alert both marked with question marks.
Schematic.
12. How does context windowing lower an agent's cost?Explain
Six bars of context size, in tokens, for turns t1 to t6, each taller than the one before.
Illustrative; no token counts.
13. Which of these is NOT part of the Claude Code Agent SDK budget surface?Explain
A large box titled budget surface inside the Claude Code Agent SDK, holding four empty dashed slots each marked with a question mark. A note says four controls belong here and one candidate does not.
Slots are deliberately empty.
14. Why can't Auto Mode's classifier stand in for max_budget_usd?Explain
Two boxes, a permission classifier from Auto Mode and max_budget_usd, the session dollar cap, joined through a circle labelled stands in, with a question about whether the first can replace the second.
Schematic.
15. When should a HITL checkpoint require a human tap in a cost-governor stack?Explain
A row of six agent steps, each with a tap question mark above and cost unknown below, asking which steps should wait for a human tap.
Schematic; step costs are deliberately unspecified.
16. When the kill switch on budget breach fires, what happens?Explain
Five agent turns followed by a red marker labelled budget breach and a kill switch box, with three questions about the session state afterward, the record of the breach, and the way back to running.
Schematic.
17. A team will run its agent in production in the EU. How should it treat logging and cap enforcement?Explain
A box for an EU production deployment containing logging and cap enforcement, each with status unknown, and a question asking how the team should treat each.
Schematic; statuses are the question.
18. An agent is stuck in a 5-second retry loop and burns about $50 every 10 minutes. Which layer should stop it first?Apply
A straight line of cumulative spend over 60 minutes rising from 0 to about 300 dollars, which is 50 dollars per 10 minutes, for an agent retrying every 5 seconds.
Computed from the stem: six 10-minute blocks at $50 each reach about $300 after an hour.
19. An agent does roughly 2x the expected work per task, with no loop and no single expensive burst. Which layer catches it?Apply
Two flat lines across tasks one to seven, one for expected spend per task and one at about twice that height for actual spend, with no spikes in either.
Illustrative: only the 2x ratio comes from the stem.
20. Every session of an agent stays under its max_budget_usd, yet total spend across many sessions keeps climbing fast. Which layer is missing?Analyze
Two panels. Left, seven session bars all below a dashed max_budget_usd line. Right, a total spend curve across sessions that keeps climbing and steepening.
Illustrative; bar heights are random, no figures.
21. You add a tool that fetches product pages to a production agent. Following the order-polling case, what should ship with it?Design
A production agent box with arrows to its existing tools and to a new dashed tool that fetches product pages. A question mark asks what this tool ships with.
Schematic.
22. You will run an Auto Mode agent overnight with nobody watching. Which setup follows the lesson?Design
A timeline from start to morning with an agent in Auto Mode and nobody watching, and three empty dashed slots with question marks for the setup to apply.
Schematic; slots are empty.
23. You enforce a velocity limit outside Claude Code. How should the cut-off and re-enable work?Design
Agent sessions connected through an external limit that watches spend to the model API, with two dashed boxes below for the cut-off and the re-enable, both unspecified.
Schematic.

Use It

main.py simulates an agent that drifts into a polling loop at turn 30, where each turn jumps from 2,500 to 8,000 tokens. It runs that trajectory under three configurations: no caps, a monthly cap only, and the layered stack. Run it and read the last column.

With no caps, the run burns through 10,000 simulated turns and about $240. The monthly-cap-only run ends identically, because the $500 cap sits above the whole run's cost and never fires. The layered stack stops at turn 200 on max_turns, for about $4.32.

The velocity limit does not trip on this trajectory at its default of $5/min. The loop spends about $0.048/min (8,000 tokens at $0.003 per thousand, one turn every 30 seconds), so the threshold is two orders of magnitude too loose. Exercise 1 has you tune it.

Check: Use It0/9
1. In the simulator's velocity check, why is window spend divided by the elapsed time inside the window rather than the nominal window width?Explain
A timeline with a run starting partway along and a now marker later, under a ten minute nominal window that begins before the run started. Below, a formula reads rate equals window spend divided by a question mark.
Schematic; spacing is not to scale.
2. In the simulator, why does the monthly-cap-only run end with the same tokens and dollars as the no-caps run?Apply
A table of two simulator runs: no caps and monthly cap only, both with 79,840,500 tokens and 239.52 dollars.
Columns taken from a real run of the lesson's main.py.
3. A normal run of an agent spends about $0.015/min, and its polling loop spends about $0.048/min. Which velocity threshold is the best fit?Apply
A number line of spend in dollars per minute with a normal run at 0.015 and a polling loop at 0.048, and a question mark for the velocity threshold.
Values from the stem.
4. With the default layered Governor and a loop that starts at turn 30, which trigger stops the simulated run?Apply
A table of the layered Governor defaults: max_tokens_per_request 10,000, max_turns 200, max_budget_usd 50 dollars, velocity 5 dollars per minute over a 10 minute window, and monthly cap 500 dollars. A question asks which trigger stops the run when the loop starts at turn 30.
Values read from the lesson's main.py.
5. The simulated loop uses 8,000 tokens per turn at $0.003 per thousand tokens, with one turn every 30 seconds. What is its spend rate?Apply
A one minute timeline marked at 0, 30 and 60 seconds with one 8,000 token turn drawn per 30 seconds, a price of 0.003 dollars per thousand tokens, and a question mark for the spend rate in dollars per minute.
Numbers from the stem.
6. The layered Governor sets max_tokens_per_request to 10,000, and loop turns use 8,000 tokens. What does the per-request cap do in this run?Apply
Loop turns 30, 31 and onward to 200, each of 8,000 tokens, above a box giving max_tokens_per_request as 10,000. A question asks what the cap does to a loop turn.
Values from the stem.
7. In the layered run, turns 1 to 29 use 2,500 tokens each and turns 30 to 200 use 8,000 each. How many tokens does the run use in total?Apply
A step chart of tokens per turn: 2,500 tokens for turns 1 to 29, then 8,000 tokens for turns 30 to 200.
Values from the stem.
8. The printed headline says the velocity limit catches a loop within minutes, yet the layered run ends on max_turns. What does this show?Analyze
A terminal showing the headline line that the velocity limit catches a loop within minutes, and the captured output row for the layered stack run: turns 200, tokens and dollars elided, stopped by max_turns.
Captured by importing the lesson's main.py; repeated spaces collapsed, token and dollar figures elided.
9. A velocity check divides window spend by the full nominal 10-minute window. At minute 2 of a run the agent has spent $1. What goes wrong?Analyze
A timeline from 0 to 10 minutes with $1 spent in the first 2 minutes, under a ten minute nominal window, and two question marks for the rate when dividing by 10 minutes and the rate over the elapsed time.
Numbers from the stem.

Ship It

outputs/skill-agent-budget-audit.md audits a proposed agent deployment's cost-governor stack and flags missing layers.

Author's Note

I'd run main.py and read the last column before the headline text. All three runs hit the same polling loop at turn 30, and the only difference is which governors are switched on. The no-caps run and the monthly-cap-only run come out identical at 79,840,500 tokens, because the $500 monthly cap sits above the roughly $240 the whole run costs. A cap set higher than anything the run can reach is the same as no cap.

The part I'd poke at is the velocity limit. The printed headline says it catches the loop within minutes, but with the defaults it never trips here, and max_turns does the stopping at turn 200. The loop's rate is about $0.048/min against a $5/min threshold. A velocity threshold only works if you set it from the agent's observed spend rate, so measure a normal run first. velocity_exceeded divides by the elapsed time inside the window rather than the nominal ten minutes, which keeps the rate from being under-reported early in a run.

Keep the simulator in proportion, too. It prices every token at a flat $0.003 per thousand and gives every turn a fixed 30 seconds. Real runs vary on both, so I'd take the ordering of the three outcomes from it and ignore the dollar figures.

Exercises

  1. Run main.py. The layered stack stops on max_turns, not the velocity limit. Lower velocity_usd_per_min until the velocity limit fires during the loop but not during normal 2,500-token turns. How many dollars does the run spend before it stops, compared with the $4.32 the iteration cap allows?

  2. Design a per-tool cap set for a browser agent (Lesson 11). Which tool needs the tightest cap? Which tool can run unbounded without risk?

  3. Read the Microsoft Agent Governance Toolkit docs. List every cap type the toolkit names. Map each to one of the failure modes (runaway loop, slow leak, bad release, surge).

  4. Price an overnight unattended run for a realistic task (e.g., "triage 50 issues in a repo"). Set max_budget_usd at 2x your point estimate. Justify the 2x.

  5. Claude Code's max_budget_usd fires on session aggregate cost. Design a complementary velocity limit you would enforce externally. What triggers the cut-off, and what does re-enable look like?

Key Terms

TermWhat people sayWhat it actually means
Denial of Wallet"Runaway bill"Agent loop generating spend with no cap to stop it
max_tokens"Per-request cap"Ceiling on a single completion's size
max_turns"Iteration cap"Ceiling on agent loop iterations in a session
max_budget_usd"Dollar kill switch"Session cost cap; aborts on breach
Velocity limit"Rate cap"Limit on spend per short window (e.g., $50 / 10 min)
Tiered routing"Small model first"Cheap model default; escalate only when classifier warrants
Prompt caching"Cached system prompt"Provider-side cache reduces re-send token cost to near zero
HITL checkpoint"Human approval gate"Human tap required before expensive action

Further Reading

Code

Ships With