The $47 Dinner: A Month-Long Autopsy of the API Charges My 'Paused' Agents Kept Making
The charge showed up on a Tuesday while I was eating pad see ew at a strip-mall Thai place in Austin. Forty-seven dollars and change to my cloud provider. Nothing catastrophic. Nothing worth a support ticket. But I hadn't deployed anything that day, and that's the part that got under my skin.
So I did what anyone in this line of work does: I opened the raw logs and refused to close the laptop until I understood every cent.
What follows is the spend autopsy. One month of API usage across four agents, one cron job I forgot existed, and a webhook that turned out to be the villain of the whole story. If you run agents — even hobby ones — you're probably carrying similar ghost traffic. Here's how to find it.
First Rule of the Autopsy: The Invoice Lies
Your billing dashboard is a summary, and summaries are where truth goes to nap. The monthly total told me I'd spent $312 on inference and embeddings. Useful? Sort of. Actionable? Not even a little.
The real picture came from exporting usage at the request level — every call, timestamped, tagged by API key. Most providers let you do this; it's just buried in an export button nobody clicks. I pulled 30 days of logs into a CSV and grouped by key.
Four keys. I expected four clean buckets. Instead, the biggest spender was a key attached to an agent I had 'paused' three weeks earlier.
Meet the Zombies
Here's what 'paused' actually meant in my codebase: the agent's UI showed a nice little toggle in the off position, but the scheduling layer — a separate queue worker — never got the memo. Every fifteen minutes, that agent woke up, checked its task list, found nothing to do, and burned tokens deciding it had nothing to do. Forever.
That's roughly 2,880 idle check-ins a month. Each one cheap. Together: about $19 of pure nothing.
Then there was the embedding job. A side project from March that re-indexed a document store on a nightly timer. The project is dead. The timer is eternal. Another $11 monthly for indexing documents nobody will ever read again.
Add the webhook — a retry loop with exponential backoff that had given up on succeeding but not on trying — and my 'paused' infrastructure was out-earning my active work in pure spend. Roughly 60% of the month's bill came from processes I believed were off.
The Three Questions That Found Everything
You don't need fancy tooling for this. Once the logs are in a spreadsheet, ask:
1. Which keys made calls in the last 24 hours, and did I expect them to? Anything calling at 3 a.m. that isn't your overnight batch job is a suspect.
2. What's the median request size per key? Agents doing real work have a rhythm — bursts of activity, then quiet. A key with perfectly uniform, tiny requests every fifteen minutes isn't working. It's breathing on life support.
3. Which keys have no owner? This one hurt. Two keys in my account had names like key_7f3a because I'd never renamed them. Untagged keys are how orphaned workloads survive. They're invisible precisely because nobody remembers creating them.
Build the Kill Switch Before You Need It
Finding zombies is reactive. The fix is boring and structural:
- Hard budget caps per key. Most providers support soft and hard spending limits. Set the hard cap at a number that would annoy you, not ruin you — $25 per key per month in my case. When a zombie wakes up, it hits the wall in days, not weeks.
- Expiration dates on every key. Rotate on a 90-day cycle. An orphaned key that dies of old age is an orphaned key that stops billing.
- A single 'circuit breaker' script that revokes all non-production keys with one command. Mine is a 20-line shell script aliased to something memorable. The night the retry loop went haywire, I ran it from my phone over SSH and the bleeding stopped in seconds.
- Tag by project, not by person.
experiments-ghostwritertells you more at autopsy time thanian-keyever will.
The Weird Emotional Part
I'll admit something slightly embarrassing: deleting the dead keys felt like closing caskets. These were agents I'd built with genuine enthusiasm in March, and their only remaining vital sign was a line on an invoice. Killing them cost me nothing technically and something emotionally anyway.
But that's exactly the trap. Sentiment is why the zombies survive. The agent isn't running anymore — it's just haunting your bill.
The Final Tally
After the purge: same active workload, same output quality, bill dropped from $312 to $138. The $47 dinner charge, traced to its source, was mostly the retry webhook and an embedding backlog that had quietly queue-jumped during a rate-limit window.
Run your own autopsy this week. Export the logs, group by key, and ask who's still breathing. Your future self — the one reading the invoice at dinner, calmly, for once — will thank you.