Never give a cloud account unlimited access to your wallet
A post I read this week: a student found AWS had quietly charged him about $1,100 over 17 months — roughly $60/month, slowly, for what turned out to be a container service he’d left running while learning. The billing alerts were going to an email he no longer checked, so it just… accumulated. The first reaction in the thread was the usual: how to get it refunded, screenshot your CPU graphs, ask nicely.
But the sharpest comment was almost a throwaway line — that a system where beginners can quietly rack up unlimited charges shouldn’t hand them the keys without a seatbelt. That’s the real story, and it isn’t a student problem. It’s a design default problem, and it bites funded startups on a much bigger scale.
The default nobody chose: unlimited liability
Here’s the thing about a standard AWS (or Azure, or GCP) account: there is no ceiling. You are not signing up for a $60/month plan. You are signing up for an account that will bill you whatever the usage comes to — $60, or $6,000, or $60,000 — and tell you afterwards. The only thing between you and an unbounded bill is your own vigilance: alerts you have to set up, on an email you have to actually read.
That’s a system that fails open — to your wallet. When something goes wrong — a forgotten task, a misconfigured autoscaler, a leaked key, a recursive function, a launch that goes viral — the account’s default behaviour is to keep going and keep charging, not to stop and ask. And the provider’s incentive is aligned with that default: an account with no cap spends more than an account with one.
Why I never opened one as a student
When I was learning, I refused accounts like this on principle. I looked for a fixed monthly plan with a hard limit: if I hit the ceiling, I got notified and the service stopped. Predictable by design. Was it slightly less convenient than handing over a card and letting the meter run? Sure. But “let them bill me whatever, and I’ll watch for it” is not a safety model — it’s a hope. For something with unlimited downside, hope is reckless.
The convenient default is unlimited postpaid because it’s frictionless for the provider. Frictionless and unbounded are a bad combination when the number at the bottom of the invoice is your money.
For a student it’s $1,100. For a startup, add two zeros.
It’s tempting to file this under “beginner mistake.” Don’t. The exact same default — unlimited liability, bill-first-ask-never — is what turns a small misconfiguration at a funded company into a five- or six-figure event:
- A leaked access key in a public repo → someone spins up GPU fleets for mining. (I wrote about a $55,000 version of exactly this.)
- A recursive function or a retry storm that calls itself, billed per invocation, over a weekend.
- An always-on dashboard re-scanning logs, or egress on a launch that hits the front page — metered services that scale with success, not with a budget.
- A staging environment nobody turned off, on the company card, for a year.
A startup with money in the bank and a shared root account is more exposed than the student, not less — bigger blast radius, more people holding credentials, and a finance team that won’t blink at $8,000 the way the student eventually noticed $60. The unlimited-liability default doesn’t get safer with funding. It gets more expensive.
The honest counter-argument
There’s a real reason production accounts don’t hard-stop at a dollar figure: you don’t want your live service to switch off because it crossed a threshold. For a real business, a hard cap that takes you offline mid-launch is its own disaster. Fair. Unlimited-postpaid exists because production wants to fail open — stay up, sort the bill out later.
But that logic applies to production. It does not apply to a student learning, a side project, a dev sandbox, or a new account with no revenue to protect — which is most accounts, most of the time. For those, fail-closed is obviously correct, and the default is backwards. (AWS has, belatedly, started fixing the very bottom of this: newer free-tier accounts are credit-capped and stop when the credits run out, instead of silently rolling into paid usage. Good — but that only covers the free tier, not the general model.)
Alerts notify. They don’t cap — and that gap is the whole problem
Here’s how thin the default safety net really is. Someone shared a neat little script on r/googlecloud this week that sets up granular billing alerts on GCP — instead of the usual notify-at-50%-90%-100%, it creates a budget threshold at every $10 of spend up to a ceiling, each one emailing you:
# a budget alert at every $10 of spend, not just 50/90/100%
for amount in $(seq 10 10 1000); do
percent=$(awk -v a="$amount" 'BEGIN{printf "%.6f", a/1000}')
thresholds+=("--threshold-rule=percent=${percent},basis=current-spend")
done
gcloud billing budgets create --billing-account="$ACCT" \
--budget-amount=1000USD "${thresholds[@]}" \
--notifications-rule-monitoring-notification-channels="$EMAIL_CHANNEL"
That’s genuinely good hygiene — you’d know within $10 instead of within a month. But read the last line: it notifies. That’s all a budget does. Google says it in its own docs, in plain words: setting a budget does not cap your usage or spend. Same on AWS. The meter keeps running; you just get a faster tap on the shoulder — which does nothing at all if the alert email goes to an inbox you don’t read, which is how the student got to $1,100 in the first place. And it only gets weaker the more you lean on it: pile on enough alerts — email, SMS, Slack, one per project — and people go alert-blind, tuning out the real one along with the noise. Any safety net that depends on a human reading a notification is one you’ll eventually ignore.
To make it actually fail closed, you have to build the part the platform leaves out: point the budget at a Pub/Sub topic (not just email) and put a small Cloud Function on it that disables billing on the project once spend crosses the line — Google documents exactly this; the function calls the Billing API, detaches the billing account, and the project’s resources stop.
And notice what that kill switch does: it turns the entire project off. For a learning or sandbox account that’s exactly what you want. For production it’s the genuinely hard call — and here’s the honest tension. The textbook answer is “never let billing take prod down.” But there’s a real argument the other way: if alerts get ignored (and they do), a hard ceiling is your last line of insurance — and a bounded outage that makes clients complain is something you’ll notice and act on, where a silent, unbounded bill is something you won’t. A capped outage can be cheaper than an unbounded invoice. So the real question isn’t whether to have a ceiling — it’s what level you set it at, and whether you can stomach it tripping. Choose that deliberately; don’t inherit “unbounded” by default.
What to actually do
The principle: match the failure mode to what the account is for.
- Learning, side projects, sandboxes: prefer providers/plans that are bounded by design — a fixed monthly box (Hetzner, OVH, a DigitalOcean / Fly / Render plan), or a prepaid/credit model that stops when it’s exhausted. Fail closed.
- If you must use unlimited-postpaid cloud: engineer the ceiling yourself — a Budgets alert on day one, to an email you actually read, plus Budget Actions that stop resources at a threshold, and keep the learning account separate from anything real so a mistake can’t reach production. (The six guardrails are the checklist.)
- Production: default to fail-open, but set the ceiling deliberately — including a catastrophe-level hard cap as last-resort insurance, sized far above normal spend — and treat the account as a loaded gun: least-privilege, no long-lived keys, anomaly detection, and a named human who owns the bill.
The uncomfortable summary: the cloud’s default billing model is built for the provider’s growth, not your safety. Convenient, yes — but you’re the one holding the unlimited liability. So the responsible move is to put the ceiling back yourself, or pick infrastructure that had one to begin with.
That’s the argument I make to the founders I work with: send me a recent cloud bill and I’ll show you where the account is fail-open and what a bounded, flat-rate version costs instead — free, within a business day. And if you just want the guardrails, the one-page cheat-sheet has them.