The launch checklist proves the app works. The restore drill protects the data. There is one more operational habit that AI-built apps need sooner than hand-built ones, and it is about money: knowing what your app spends before an invoice tells you.
Every builder who runs on managed services eventually has the moment — an email with a number in it that does not match the number in their head. Whether that moment costs you a coffee or a mortgage payment depends entirely on plumbing you can set up in one evening, now, while everything is calm.
Why AI-built apps bill differently
Three reasons this habit is more urgent when an agent built the product:
- Agents provision casually. Getting a feature working often means adding a service — an image API here, a queue there, an email provider, a bigger database tier. Each one arrived as a step in a task you approved, not as a purchasing decision you weighed. Multiply by a few weeks of building and you have a stack of metered services no single person ever saw as a list.
- Everything is usage-based. The modern stack mostly has no price tag, only a meter: per request, per gigabyte, per row, per token. Usage-based pricing is wonderful at small scale and unbounded by construction. The bill is a function of what happens, and you do not fully control what happens.
- Your app may resell an expensive API. If your product calls a model API in production, every request a user triggers is real money leaving your account. That is a new thing! A traditional CRUD app's marginal cost per request rounds to zero. An AI feature's does not — which means a runaway loop, an enthusiastic user, or a scraper hammering an endpoint converts directly into spend.
To be clear about scope: this is not about what you spend on agents while building — that is its own discipline, covered in how to not waste tokens. This is about what your running app spends while you sleep.
Step 1: the spend inventory
You cannot watch what you cannot list. Take fifteen minutes with your card statement and your inbox's sign-up receipts, and write down every service your app touches that has billing attached. For each one, three columns:
- The pricing axis. What does the meter count — seats, requests, storage, compute hours, tokens?
- What you expect to pay this month. A guess is fine; the point is to have a number to compare against.
- The unbounded one, flagged. For each service, ask: if something went wrong, is next month's bill capped, or is it open-ended? Fixed-price tiers fail closed. Metered APIs fail expensive.
Keep it as COSTS.md in the repo. A made-up example, to show the shape (illustrative numbers, not a benchmark):
Hosting — per seat + bandwidth — expect $20 — capped by plan. Database — storage + compute — expect $25 — grows with usage, soft-capped. Model API — per token — expect $30 — unbounded, user-triggered. ⚠
That last row is where the rest of this post lives.
Step 2: alerts before caps
Every major provider has budget alerts — an email or webhook when spend crosses a threshold you set. They are free, they take two minutes each, and almost nobody configures them before their first bad invoice.
Set two thresholds per service, working from your expected number:
- Roughly 1.5× expected: "look at this." Something changed — maybe growth, maybe a bug. Either way you want to know mid-month, not from the invoice.
- Roughly 4× expected: "stop what you are doing." This one goes to the channel that actually interrupts you.
An alert does not stop the spending — that is the next step — but it converts detection time from a billing cycle to hours. Most horror stories about surprise bills are really stories about silence: the meter ran for three weeks because nothing was configured to speak up.
While you are in each dashboard, check one more thing: that billing emails go to an address you read. Spend alerts routed to an unwatched inbox are decoration.
Step 3: caps, and knowing which way they fail
Where a hard limit exists, decide deliberately whether to use it.
Model API platforms generally let you set monthly spending limits per key or per project. Some hosts let you cap usage-based features. When a cap is hit, the service stops serving — which sounds bad until you compare it with the alternative.
The question to answer per service is: when the meter runs away, do I want this to fail closed or fail open? Fail closed means your feature degrades and users see an error; the blast radius is a bad day. Fail open means the feature keeps working and the meter keeps running; the blast radius is your bank account. For a pre-revenue product, fail closed is almost always the right default for the unbounded rows in your inventory — a capped model API that goes dark at 3 a.m. costs you some goodwill; an uncapped one can cost more than the product has ever earned.
Whatever you choose, make it a choice. The worst position is not knowing which behavior you have.
Step 4: guard the endpoints that spend money
Alerts and caps are the outer walls. The inner wall is not letting strangers spend your money in the first place. Any endpoint that turns an incoming request into a paid API call — the model-powered feature, the image generator, the enrichment lookup — needs three things:
- Authentication. An unauthenticated endpoint that calls a paid API is an open tab with your card behind the bar. Automated scanners probe for exactly this shape of endpoint; assume it will be found eventually, because that is the safe assumption to build on.
- Rate limiting. A per-user, per-window ceiling on requests. It protects you from scripts, scrapers, and your most enthusiastic user's infinite-scroll reflex alike.
- A per-user budget. Beyond rate limits: a daily or monthly quota of the expensive action per account, enforced server-side. Generous is fine. Infinite is not.
One logging line completes the wall: record every paid call with the user who triggered it. When an alert from Step 2 fires, this is how a mystery becomes a five-minute answer — which user, which endpoint, since when.
The monthly look
Last habit, smallest one: a recurring half hour, once a month, with COSTS.md open next to the actual invoices. Compare each line to expectation. Update the expected numbers as the product grows. And scan for services that no longer earn their line — agents are quick to provision and never come back to decommission, so subscriptions outlive the features that needed them.
The agent's role
Prompt-sized, as always:
- "Find every endpoint in this app that triggers a paid third-party API call. For each, report whether it requires auth and whether it is rate limited."
- "Add per-user rate limiting and a per-user daily quota to [endpoint]; return a clear error when the quota is hit. Log each paid call with user id and endpoint."
- "Write COSTS.md from the services in this codebase's config and env vars: pricing axis, expected monthly spend placeholder, capped or unbounded."
Set the dashboard alerts yourself — they live in provider accounts the agent should not have credentials for anyway.
The receipt
The finished state is a COSTS.md where every service has an expected number, two alert thresholds, a written fail-closed-or-open decision on the unbounded rows, and a "last reviewed" date under a month old — plus auth, rate limits, and quotas on every endpoint that spends.
The app is launched, backed up, and watched. This is the last quiet piece: making sure the thing you built stays something you can afford to keep running.