guide · ai

Why every agent needs a cost cap on day one

Three numbers, one enforcement point, and a hard ceiling before the bill lands. The cheapest pattern that separates an agent you run from one you babysit.

July 22, 2026 · By Agentic Bot Sitter

Retro editorial illustration of a chrome-domed robot pointing at a red gauge pegged at the limit, with sparks flying from an interrupted circuit and a glowing red emergency stop button.

The day an agent cost $80 in an hour is the day you stop trusting “we’ll watch it.” The pattern is the same every time: an infinite-loop prompt kept calling a frontier model with a large context window, the loop ran 200 times before anyone noticed, and the bill landed before the alert.

A cost cap is not a fancy observability feature. It is the difference between an agent you run and an agent you babysit. The cost-cap pattern is the one every metered API recommends — OpenAI’s rate limits guide, Anthropic’s rate limits, AWS billing alarms, and Stripe’s usage-based billing alerts — the industry converges on hard ceiling plus soft warning.

Before you start

You need:

  • A Python function that calls your model of choice (any framework).
  • A writable directory for the JSONL ledger (any path your agent can append to).
  • A way to inspect the ledger (wc -l, awk, or your editor of choice).

No cloud account, no paid service, no special library.

The minimum viable cost cap

You need three numbers and one enforcement point.

- per-run ceiling     $1.00
- per-day ceiling     $5.00
- per-week ceiling    $25.00

The enforcement point is before the model call, not after. After is a bill. Before is a circuit breaker.

# pseudo, fits any framework
def call_model(prompt, run_id):
    cost_so_far = ledger.cost(run_id=run_id, scope="run")
    if cost_so_far >= RUN_CEILING:
        raise CostCeiling("run", RUN_CEILING)

    cost_today = ledger.cost(scope="day")
    if cost_today >= DAY_CEILING:
        raise CostCeiling("day", DAY_CEILING)

    cost_week = ledger.cost(scope="week")
    if cost_week >= WEEK_CEILING:
        raise CostCeiling("week", WEEK_CEILING)

    response = model.complete(prompt)
    ledger.record(run_id, model, response.tokens, response.cost)
    return response

That is the whole thing. A ledger, three ceilings, one check.

CommandJobSuccess state
RUN_CEILING = 1.00 (constant)Sets per-run dollar cap.Editing the constant changes the per-run limit; reload takes effect on next run.
DAY_CEILING = 5.00Sets per-day dollar cap.Same — change at the top of the file.
WEEK_CEILING = 25.00Sets per-week dollar cap.Same.
ledger.cost(scope=...)Reads accumulated cost for the scope.Returns a float in USD; raises if ledger is missing.
raise CostCeiling(scope, value)Stops the call before it happens.Caller sees the exception and the value that triggered it; ledger is unchanged.

Hard ceiling vs soft warning

Two flavors, both useful. The OpenAI rate limits guide and the AWS billing alarms docs both describe this split.

  • Hard ceiling: the call is refused. No exceptions. Use this for per-day and per-week.
  • Soft warning: the call goes through, but the agent is told “you are at 80% of today’s cap.” Use this for per-run so the agent can finish a legitimate task without being cut off mid-stream.
if cost_so_far >= RUN_CEILING * 0.8:
    log_warning(f"run at {cost_so_far/RUN_CEILING:.0%} of cap")

if cost_so_far >= RUN_CEILING:
    raise CostCeiling(...)

What the ledger looks like

A tiny JSONL append-only log is enough.

{"ts":"2026-07-20T13:11:04Z","run_id":"7c2a","model":"claude-sonnet-4","tokens_in":482,"tokens_out":124,"cost_usd":0.0014}
{"ts":"2026-07-20T13:11:09Z","run_id":"7c2a","model":"claude-sonnet-4","tokens_in":211,"tokens_out":38,"cost_usd":0.0006}

A run-end line rolls up totals.

{"ts":"2026-07-20T13:11:14Z","run_id":"7c2a","kind":"end","total_cost_usd":0.0022,"status":"ok"}

You do not need a database. You need wc -l and awk '{s+=$NF} END{print s}'.

The 1-minute review

After a week of running with the cap, answer these in 60 seconds:

1. What was my most expensive run this week? (probably an image/video gen burst)
2. What model was it? (probably a frontier one I called by accident)
3. Did the cap save me anything? (almost certainly yes)

If the answer to #3 is no, your ceilings are too high. Lower them until the cap fires at least once a week. A cap that never fires is not a cap, it is a number.

How to know it is working

The cap is working when CostCeiling fires at least once a week. The cap is also working when the agent sees the 80% soft warning and finishes its task anyway. The cap is not working if no exception has fired in 30 days — the ceilings are too loose, or your agent is not running.

Common failures and fixes

FailureCauseFix
The cap never fires.Ceilings too high; agent not running.Lower ceilings until the cap fires at least weekly.
The cap fires on a legitimate task.Per-run ceiling too tight for the model you call.Move that model class to per-day scope; raise per-run to $2 or $5.
The ledger has gaps.Agent crashed before recording.Add try/finally around the ledger write.
CostCeiling is raised but the next call still goes through.Caller catches the exception and retries.Hard-fail at the entry point, not in the caller’s retry loop.

When not to use this pattern

  • Sub-cent runs at low volume. If your agent runs five calls a day on a cheap model, the ceiling logic is overhead, not protection.
  • Models you trust and have already cost-capped at the provider. If your OpenAI org has a $50/day hard limit set in the dashboard, your local ceiling can be a soft warning only.
  • Anything where “fail the call” would corrupt state. A long-running migration that aborts mid-write is worse than the bill. Set a checkpoint-and-resume pattern first, then a ceiling.

Updates and breaking changes

Re-run the 1-minute review after any of these:

  • You switch model providers (cost ceilings are model-specific).
  • You add a new tool that calls a paid API (image gen, transcription, web search).
  • Your provider changes its per-token pricing — re-read OpenAI pricing or the equivalent page monthly; ceilings that were loose last quarter may be tight this quarter.

A ceiling tuned six months ago is a guess today. Verify it.

Where to get unstuck

  • OpenAI: the rate limits guide is the authoritative reference; if you hit a 429 you cannot explain, file a ticket with the Request-ID from the response headers.
  • Anthropic: rate limits page lists tier-by-tier limits; the help center accepts tier-increase requests.
  • Independent: HN threads on agent cost-runaway loops — multiple “my agent burned $X in an hour” stories; consistent recommendation is “hard ceiling from day one.”
  • File a bug: include your ledger path, the run_id of the failed call, the model name, and the dollar amount that slipped through.

Sources

Last verified: 2026-07-22. Reviewer lineage: drafter and fact-checker are the same model (MiniMax-M3). Where a quote is paraphrased from memory rather than retrieved from the source, the paraphrase was cross-checked against the canonical URL on 2026-07-22.

Sources

#agents#setup#observability#cost

Submit a take

Have a different read on this? Drop a comment below — your email isn't published, and I read every one. Nothing leaves the site until I approve it.

Your email address will not be published. Required fields are marked.