Each placement fails in a different way, and the failures are not interchangeable.
Gateway budgets fail open. A missing database, a misconfigured global setting, a deployment without persistence, and the budget becomes a log line. The LiteLLM documentation warns that a budget configured with no database logs a warning once at startup and then serves requests past the limit per the LiteLLM budget docs. Test the failure path deliberately: set a tiny budget, confirm the rejection, then remove the database and confirm you know what happens.
Gateway budgets overshoot by design. Between the response that crosses the limit and the next request that is refused, real spend lands above the cap. Kuadrant's reservation model reduces the race but does not eliminate overshoot, because reservations are estimates and the actual committed usage can exceed them per the Kuadrant docs. A cap of 1,000 tokens per minute with one request returning 1,200 tokens will let that request through and block the next, as agentgateway documents explicitly per the agentgateway docs. Size the cap with headroom, not at the exact number you can afford.
Service checks miss the multi-service sum. A per-call ceiling of 24,000 tokens in five services gives you no protection against 5,000 calls. Attribution layers exist for exactly this gap: provider consoles aggregate by API key or project and cannot tell you which team, feature or agent run spent the money, which is the reason gateway and SDK tagging became standard practice per TrueFoundry's cost attribution write-up.
Service checks mis-count. Wrong tokenizer, missing image tokens, ignored per-message overhead, tool schemas left out of the count. Any one of these turns a hard cap into a soft one with extra steps. The prompt token counter documentation is a useful reminder that the count you see in a playground is only meaningful if the tool uses the provider's tokenizer for the exact text you will send per the prompt token counter reference.
Prompts fail silently. Nobody finds out the instruction stopped working until the invoice arrives, because the model does not report non-compliance.
Retries and tool loops fail everywhere unless you plan for them. Retry storms are one of the recurring causes of unexplained spend spikes: transient provider errors trigger SDK retries with backoff, the application logs only the successful response, and the retry tokens never surface locally per the Braintrust playbook. An agent that calls a tool, receives a malformed result and tries again bills every iteration. Whatever counter you build has to run on every attempt, not on the request your code made once.
A control architecture that handles all of this looks layered, not singular. Hard caps at the gateway for aggregate spend across callers you do not control. Pre-flight checks with the correct tokenizer in each service, plus a request-level output ceiling. Alerts with a drift threshold, never as the only line of defense. And a named owner per budget, because a cap nobody owns is a cap nobody tests. The distinction between a soft alert, a constrained mode that degrades to a cheaper model and a hard cap that stops serving is itself a business decision about whether interruption costs more than the overrun per the NHI Management Group FAQ.