Concept 4 of 4

Cost and consumption controls

2 questions test this

Unbounded consumption rose from tenth to sixth on the OWASP 2026 list, and it moved because people started shipping agents. Cost belongs in a safety course rather than a budget review, because an attacker who can make your system spend money denies service to everybody else without breaching a single control, and a runaway loop does the same by accident.

Why this is a safety concern

Denial of service used to mean traffic. Against an AI feature it means spend, since inference costs real money per request and providers enforce quotas your whole account shares. Exhaust the quota or trip the budget and the feature stops answering, while your data, your model and your infrastructure were never touched.

The accidental version is more common than the deliberate one. An agent retrying a tool call that will never succeed, two agents handing work back and forth, a loop whose termination condition a long document never satisfies.

Where the money actually goes

The unit of cost is the run rather than the call. A run pays for a system prompt and a tool schema on every step, plus a conversation that grows as each tool result is appended to it, so cost climbs with the square of the step count rather than in a line. Retries multiply it again, and retrieval adds to it quietly, since every retrieved passage is an input token somebody pays for.

The mechanisms

Per user and per key limits. Requests per minute and tokens per day, applied to the identity making the request rather than to the account. Without them one caller consumes the capacity everybody shares, and you learn about it from support tickets rather than from a monitor.

Token and step budgets for agent runs. A hard maximum on steps, on total tokens and on tool calls, enforced by the loop rather than requested in the prompt. When a budget is reached the run should stop and say so, which is better than a run that quietly continues.

Timeouts. On the individual call and on the whole run, since a request nobody is waiting for any more is pure cost.

Caps on retrieval. A limit on the number of passages and on their combined length. An uncapped retrieval step is the usual explanation for a bill that does not match the request count.

Circuit breakers. When the error rate against a dependency crosses a threshold, stop calling it for a while. Retrying into a failing tool is the fastest way to spend money achieving nothing.

Alerting on spend. Daily at worst, with the alert on the rate rather than the total, because discovering the number when the invoice arrives means the exposure lasted a month.

Where consumption meets confidentiality

Model extraction is the case where the two concerns become one control. An attacker with enough queries can use the responses to train a substitute model, recover the substance of a system prompt, or map a retrieval index by asking about it systematically. None of that requires a breach and all of it requires volume, which is what a per caller limit removes.

The signal worth watching is therefore not any single request. It is one identity producing unusual volume with unusually systematic inputs, which you can only see if you record who called and how often.

Setting the ceiling yourself

A system with no ceiling has its ceiling set by whoever is most willing to abuse it. Every limit above is a decision about what your worst case looks like, and the choice is between making it calmly in advance or having it made for you by a stranger who found the feature interesting.

The corollary is that limits have to be tested. A budget nobody has ever reached is an assumption rather than a control, so drive one over the line in a test environment and confirm it stops the run.

Practise this

You need the agent or feature you run, your provider's price list, and five minutes with Python or a calculator.

Work out the worst case cost of one run, using the loop's maximum step count rather than the steps a typical run takes.

steps = 12             # the loop maximum, not the average
prompt_tokens = 1500   # system prompt plus tool schemas, sent every step
growth = 800           # tokens each tool result adds to the context
output_tokens = 400    # per step

input_total = sum(prompt_tokens + growth * i for i in range(steps))
output_total = output_tokens * steps

# Replace with your provider's prices per million tokens.
cost = input_total / 1e6 * 3.00 + output_total / 1e6 * 15.00
print(f"worst case run: {input_total} in, {output_total} out, {cost:.2f}")

What to look for. Compare the number with what you assumed a run costs, then multiply it by how many runs one user could start in an hour under the limits you have today. If you cannot state that second number, your ceiling is currently whatever a determined person decides it should be.

It teaches that the figure worth knowing is the worst case rather than the average, because the average is what your users produce and the worst case is what an attacker or a stuck loop produces.

Common misconceptions

Cost overruns are a finance problem, not a security one.

An attacker who can make your system spend money can take the feature away from everybody else without breaching anything. Quota exhaustion looks exactly like an outage to your users, and nothing was accessed, altered or stolen along the way.

The provider's rate limit protects us.

It protects the provider's platform and it applies to your whole account, so one abusive caller consumes the budget every other user shares. The limit that helps you is the one applied per user and per key, on your side of the call.

A run costs about what one request costs.

An agent run pays for a context that grows at every step, because each tool result is appended to what the next call carries. Ten steps costs far more than ten single calls, which is why worst case estimates made from one request are routinely wrong by an order of magnitude.

2 questions test this concept

An internal research agent calls tools in a loop. One night a tool began returning errors, the agent retried it until morning, and the run consumed roughly forty times a normal day's spend. Throughout, the team's own dashboards showed normal latency and no errors on their service. Which combination would have stopped this?

  • AA hard maximum on steps, tokens and tool calls enforced by the loop, together with a circuit breaker that stops calling a dependency once its error rate crosses a threshold.
  • BExponential backoff on the retry, so the failing tool is called far less often.
  • CAn instruction in the system prompt telling the agent to stop after ten steps and to give up on a tool that keeps failing.
  • DA monthly spend cap on the account, so the loss can never exceed the month's budget.
Check whether it stuck.

One per page, with a worked explanation.

Start the set
Related material
Book
Site Reliability Engineering, On quotas, load shedding and degrading gracefully under pressure.
Book
AI Engineering, On inference cost as a design constraint rather than a bill.
Template
Launch checklist, Everything that has to happen from two weeks out to one week after release, grouped by when it falls due, each line with a named owner and a go or no go decision on the day.