XavierFok
← all posts

The overnight bill that made me give my AI agent a budget

2026-08-15 · by Xavier Fok

# The overnight bill that made me give my AI agent a budget

A few months ago I left an agent running overnight on a boring research task and woke up to a bill that made my stomach drop. No drama had occurred. The agent had simply gotten stuck: a step failed slightly, so it tried again, and again, all night, each attempt costing a little money, thousands of attempts deep by morning. It had quietly spent far more than the task was ever worth on a problem it was never going to solve.

The lesson should have been obvious in advance. Anything that can act on its own and spend while doing it needs a spending limit, for the same reason no company hands out a card with no cap. So I built one. This is how the budget works, why it lives where it lives, and what it honestly can and cannot protect me from.

Why agents run away

A normal program executes a fixed list of steps and stops. An agent runs a loop instead: observe the situation, pick a next action, take it, then look at what changed and pick again, on and on until it judges the job done. That loop is what makes agents worth using, since they adapt where a script would give up. The same loop is what makes them dangerous to a wallet.

The fragile part is the finish line. A confused agent, an impossible task, a misread of its own progress, and the moment of done never arrives. The loop does not crash. It keeps going, perfectly content, with no idea it is getting nowhere, and every pass costs money.

Every step of the loop is metered

Models charge by the amount of text they read and write, measured in tokens. One pass of the loop, reading the situation and deciding what to do next, might cost a fraction of a cent, which sounds harmless and is harmless, once. But an agent takes more than one step. A hard task takes dozens or hundreds, and a stuck agent takes thousands without blinking.

So the real cost is the per-step price multiplied by however many steps the agent chooses to take, and that second number sits outside your direct control. The model decides how long to loop, and every pass ticks a meter that never displays itself anywhere. Nothing in a basic agent setup ever says stop. Once I understood that, the overnight bill made complete sense. It was never an anomaly. It was the default behavior, waiting for the right kind of stuck.

Counting came first

The fix started with something embarrassingly basic: I began counting. Every step my agent takes now gets its token usage and cost recorded and added to a running total for that task. At any moment I can see exactly what this particular job has spent so far.

That sounds too small to matter. It is the foundation for everything else, because a number you never measure is a number you cannot limit. Before the counter, spending was invisible until the invoice arrived at month end, the worst possible moment to learn anything. After it, cost became a live figure climbing in real time while the agent works. A runaway loop stopped being a mystery I discover later and became a number I can watch, and a number you can watch is a number you can act on.

The cap lives outside the model on purpose

Before the mechanism, the design decision, because this is the part people get wrong. The tempting shortcut is to put the limit in the prompt: please watch your spending and stop when it gets high. That approach fails for a structural reason. The model is the component that gets confused and loops in the first place. Asking the confused component to also be the responsible adult supervising itself is backwards, and when the model is stuck, a polite instruction buried in its prompt is the first thing that stops mattering.

So the meter and the limit live in plain code, outside the loop, where the model cannot see them and cannot override them. This pattern repeats across all safe automation: never trust the thing being limited to limit itself. Put the brake somewhere the machinery cannot reach, so the brake still works no matter how badly the machinery misbehaves.

With a running total in place, the budget itself is almost nothing. Before a task starts, I set a number: this job may spend fifty cents and no more. At the top of every loop pass, before the agent takes its next step, my code performs one check. Budget left? Take the step. Budget gone? The loop ends there. The agent gets no vote, because the decision was never the agent's to make.

What hitting the wall looks like

The stop is clean and it is loud. The agent halts, reports how far it got, and says what it was about to try next. Then it waits for me.

Now the call the agent could never make for itself lands with me, in the moment, while it is cheap. Sometimes the task was genuinely close to done, so I grant a little more room and let it finish. Sometimes it was hopelessly stuck, so I kill it, out fifty cents instead of fifty dollars. Either way I find out immediately, and a tool that stops to ask a human beats a tool that confidently spends money into the ground.

A warning light before the wall

A hard stop on its own felt blunt, so I added one refinement. When a task crosses roughly eighty percent of its cap, the agent sends me a quiet heads up: this job is getting expensive and is approaching its limit.

The early warning changes how the cap feels in practice. Sometimes I glance over, see the agent on a sensible path that simply needs more room for this particular job, and raise the cap before anything stops. Other times the warning is my first hint that something has gone sideways, and I step in early. The wall remains the real safety net. Most days the warning light means the wall never comes into play.

What a budget cannot do

A budget is a blunt instrument, and pretending otherwise would be selling you something. It has no idea whether the money bought progress. An agent grinding usefully toward a result and an agent spinning in a circle look identical to a counter; both just accumulate cost. So the cap will occasionally cut off a task that was about to succeed because it ran slightly over, and yes, that is annoying.

It also guards exactly one thing: the wallet. An agent that does something wrong but cheap sails straight past a spending cap. Reviewing what an agent is allowed to touch in the first place remains a separate and more important job. I think of the budget as one specific seatbelt rather than the whole car. It catches the one failure that actually bit me, the runaway cost, and it catches that failure reliably.

Cheap to build, and one decision stays mine

The build cost almost nothing. A counter plus one check at the top of the loop, an afternoon of work, paid back many times over in bills that never happened. Running it is free, since counting tokens is bookkeeping on data the agent already produces.

The one input that still requires judgment is the number itself. A quick research job might deserve twenty cents. A big important one might deserve ten dollars. Only I know what a given task is for, so setting its worth stays with me, as it should. You never hand the valuation of the work to the thing doing the spending.

The quiet failure lesson

What stays with me most is how silent the original failure was. No error, no crash, no warning. By every technical measure the agent was working: taking steps, making requests, getting responses. It just did all of that in a tight circle going nowhere, and nothing in the system considered that a problem, because nothing was looking. The dangerous failures in automation are rarely the loud ones. They tend to resemble success while burning through money or time, and a budget is one way to force a quiet failure to become loud, by giving it an edge it will eventually hit. Once I started thinking in those terms I went hunting for other silent runaways in my setup, and found a couple. That mindset ended up worth more than the budget itself.

If your agents can act alone and spend real money doing it, build this before anything fancier; it is the cheapest insurance you will ever write. If you only ever chat with a model by hand, you are the loop, and you will stop on your own. The moment the loop belongs to the machine, it needs an edge, because it will never find one itself. I write about the unglamorous guardrails that keep automation trustworthy at [xavierfok.com](/).

Get new guides and videos first — join the Telegram channel.