Update: a few things landed since this was published. v0.2 added a Redis shared store so multiple workers can share one cap. After that came an onSpend hook (per-call cost events), streaming usage for OpenAI/Anthropic/Gemini, monthly caps with timezones, and adapters for Vercel AI SDK, LangChain.js, LlamaIndex.TS and Mastra. As of v0.6 the caps are also concurrency-safe (atomic reservation) and there's a built-in pre-call estimator, so over-budget calls get blocked before they're sent.
We've all seen the screenshot: someone leaves an agent running overnight, a retry loop goes sideways, and they wake up to a bill that's 10x what they expected — "$40 from a $5 task." The scary part isn't the money, it's that nothing stopped it. You find out when the invoice lands.
I wanted the dumbest possible fix: a hard cap that just blocks the next call when you're over budget. Not a dashboard I have to remember to check, not a gateway I have to deploy. So I built budget-guard — a tiny drop-in wrapper for the OpenAI/Anthropic clients.
The whole idea in 3 lines
import { guard } from 'budget-guard';
const ai = guard(openai.chat.completions, { project: 'my-app', dailyCapUSD: 50 });
await ai.create({ model: 'gpt-4o', messages }, { feature: 'summarize' });
Once today's spend for my-app crosses $50, the next create() throws BudgetExceededError before it bills you. A runaway loop dies at the breaker instead of draining your account. It stays out of your critical path — your calls still go straight to the provider; budget-guard just meters the usage and trips when you're over.
Bonus: where did the money go?
It tags spend per feature, so you can finally answer "what cost that?":
import { spendReport } from 'budget-guard';
spendReport('my-app'); // → { summarize: 2.41, chat: 0.88 } (today, USD)
It auto-detects OpenAI (prompt_tokens/completion_tokens) and Anthropic (input_tokens/output_tokens) usage shapes; for anything else you pass a one-line extractor.
Being honest about v0.1
I'd rather tell you the limits than have you find them on an invoice:
- In-memory, per-process. Great for a single script, agent, or worker. Run multiple instances and the cap is per-instance and resets on restart. A shared (Redis) store is the obvious next step.
- Enforced on the next call. No pre-call token estimation yet, so one call can overshoot before the breaker trips.
- Prices are a hand-maintained table. PRs welcome to keep them current.
So today it's best for solo devs, side projects, and single-process agents — exactly the people most likely to get surprised by a bill.
Try it / break it
npm i budget-guard
MIT, no runtime deps, TypeScript. Repo: https://github.com/kimbeomgyu/budget-guard
I'd love feedback on two things: should it block by default, or warn + callback? And if you run a fleet, would a Redis-backed shared cap actually get used, or do you already handle this at a gateway layer? Issues and PRs very welcome.
Top comments (2)
This is a very practical first layer of protection. A lot of agent cost problems start as retry loops or unattended scripts, so a hard local breaker is valuable even before a team has a full gateway or observability platform. I like that you’re honest about the single-process limitation; a Redis/shared-store version would make this much more useful for worker fleets. I’m exploring local-first agent debugging in agent-inspect, and cost caps plus execution traces feel like two sides of the same safety story.
Thanks Raju, and funny timing on the Redis point: that actually shipped in v0.2 right after I wrote this. There's a pluggable SpendStore now with a Redis adapter, so a whole worker fleet shares one cap instead of every process keeping its own count. If you want to poke at it there's a runnable redis-fleet example in the repo.
Also your "cost caps + execution traces are two sides of the same safety story" comment stuck with me. I ended up adding an onSpend hook because of it. It fires a small event per call (project, feature, model, usd, day total so far) that you can pipe into whatever logging you already run. The cap stops the bleeding, the hook tells you where it came from.
Will keep an eye on agent-inspect. Cost as one more signal next to the trace makes a lot of sense.