Blog
Spend without becoming a billco
At some point every team running LLM-backed agents in production asks the same quiet, slightly nervous question: "wait, what happens if one of these starts looping and just... keeps calling the model?" FinOps on the plane exists to answer that question before it becomes an incident report — and to answer it honestly, which turns out to be harder than it sounds.
The failure mode this actually guards against
An agent that gets stuck in a retry loop, or a prompt that quietly triggers a much longer tool-call chain than anyone expected, doesn't fail loudly. It fails expensively. Nothing crashes. Nothing pages anyone. The bill just arrives at the end of the month noticeably larger than it should be, and by then the loop that caused it ran its course days ago and left no obvious trace beyond the invoice. That's the specific, unglamorous problem FinOps on the plane is built to catch while it's still happening, not after.
The fix isn't a dashboard that tells you about the problem after the fact — you can build that yourself with any logging pipeline. The fix has to be a control that can actually say no, at the moment a new run is about to start, before the money is spent rather than after. That's the difference between monitoring spend and governing it, and it's the reason budgets live at admission time — the same gate that checks kill switches and authorization — rather than in a report you read the next morning.
What "governing" actually means here: caps, not invoices
Budgets are set per tenant and, if you want finer control, per tenant-and-agent pair: a maximum USD spend per UTC day, a maximum token count, a maximum number of runs. Cross a soft cap and the plane lets the run through but records an alert — useful for "we're approaching the limit, someone should look at this" without anyone's legitimate work getting blocked. Cross a hard cap and new runs in that scope are refused outright, admission-time, before a runner is ever dispatched. There's also an opt-in, more aggressive option for when a hard cap is already blown: cancel whatever's still in flight in that scope instead of just refusing new work, for the cases where "stop the bleeding immediately" matters more than "let currently-running work finish."
None of this requires the plane to know anything about how you actually get billed. There's no invoice, no payment method, no subscription tier changing based on usage. A budget is a ceiling the plane enforces on itself, using numbers you configured, computed from real token counts the model provider reported. It's closer to a resource quota than a billing system, and that's deliberate — the plane's job is to stop you from finding out about a runaway agent from an invoice, not to become the thing that generates the invoice.
The estimate is honest about being an estimate
Here's the part that's easy to get wrong, and where a lot of "cost tracking"
features quietly start lying to you: the dollar figure Admin shows is
labeled Estimated USD, not Cost, and that label is load-bearing,
not decoration. Token counts are exact — they come straight from the model
provider's own response metadata, the same numbers the provider itself would use
to bill you. Dollars are a separate calculation: your own configured price-per-
thousand-tokens for that specific model ID, multiplied against those exact token
counts — unless the runner happens to be talking through a gateway that reports
cost inline with usage (OpenRouter's usage.cost is the concrete
example this codebase actually handles), in which case that reported figure is
used instead and the local pricebook is skipped for that one run.
What happens when a model gets swapped and nobody remembers to add its price to
the pricebook? The honest answer is: the token count still gets recorded
correctly, the dollar figure resolves to zero, and the plane raises an alert about
it — usage_unpriced — instead of silently showing a low number that
looks fine at a glance but is quietly wrong. And if a reply comes back from a
provider or framework integration the plane has never seen the shape of before,
so it can't find token data anywhere it knows to look, that raises a different
alert — usage_unmetered — because the one outcome worse than
under-pricing a run is making it invisible to the whole system, indistinguishable
from an agent that made no LLM call at all. Both of those are the plane telling
you "I don't actually know the answer here" instead of guessing and presenting
the guess as fact.
What this deliberately doesn't try to be
It's worth being direct about the boundary. This is not a billing platform. There is no invoicing, no multi-currency support, no reconciliation against your actual provider account balance after the fact, and no attempt to shop automatically across model providers for the cheapest option — the closest thing to automatic cost optimization here is an opt-in rule that reroutes to a cheaper, pre-approved alternative agent once spend gets close to its soft threshold, and even that only fires within aliases you explicitly configured. If what you actually need is a product that handles payments, subscriptions, and customer-facing invoices for usage-based pricing, that's a different category of tool, and pretending otherwise would make this section dishonest. What FinOps on the plane promises is narrower and, for the specific failure mode it targets, more useful: agents don't get to spend money nobody approved, and when the plane isn't sure what something cost, it says so instead of making up a number.
Try it
Previous: BYO runner, governed secrets · Spend (FinOps) docs · Run manifest · Blog index
That's the series for now — back to the blog index for what's next, or the chapters for a slower, more methodical walk through the same ground.