AI & Machine Learning

The Bug That Ships as a Feature: What I Learned About Spend Caps the Hard Way

A

Admin User

Author

Jul 19, 2026
5 min read
15 views
The Bug That Ships as a Feature: What I Learned About Spend Caps the Hard Way

I shipped a broken spend cap last month. Not catastrophically broken—nothing caught fire—but broken in a way that made me realize I didn't actually understand what my own rate-limiting code was doing when the database went down.

It was 2 AM, our API was getting hammered, and the pricing oracle timed out. My cap didn't refuse requests. It didn't block them either. It just... kept going. And I only realized because a customer's bill was wrong. The decision I'd made about how to handle a missing price wasn't actually in my code—it was hiding in what I didn't write, in the exception handling I skipped because I assumed something else would catch it.

Reading this article about spend caps and oracle failures felt like someone had installed a camera in my apartment. I'm still thinking through the implications.

The Problem Is Worse Than the Framing

The traditional way we talk about this is "fail-open vs fail-closed." Fail open means you let requests through when you can't price them. Fail closed means you block everything. This framing made me feel clever—I could pick a side, add a config option, and move on.

But the article fundamentally breaks this apart. The real axis isn't open or closed. It's whether your ledger keeps counting.

When your pricing oracle goes down, you have a few choices. You can refuse requests (truly fail-closed). You can admit them without charging anything (ledger frozen). You can charge a pessimistic estimate. You can fall back to a local model. On paper, these look different. But some of them produce identical behavior—they both charge zero, they both stop the ledger from moving, they both create unaccounted-for actions in your system.

The article proves this with a cryptographic hash. Two different policies, different names, different philosophy, identical byte-for-byte decision streams. One gets called a bug. The other gets called the recommended fix. The difference is branding, not behavior.

This broke something in how I think about safety. I've been treating "use a local fallback model" as obviously more sophisticated than "fail-open." And it is more sophisticated in terms of user experience. But if both charge zero when the oracle is down, both have the same ledger problem. Neither solves the core issue.

The Real Cost: Moving vs Frozen Ledgers

Here's where it gets practical. If your ledger stops counting (zero charges), then when the oracle comes back online, you have no way to know what happened during the outage. Those 34 unpriced actions in the test scenario? They're ghosts. You can't audit them. You can't charge for them. You can't even know if someone exploited the gap.

But if you charge something—even a wildly inaccurate estimate—your ledger keeps moving. You have a floor. It might be wrong (a $0.05 action priced at $0.01), but at least there's something to audit and correct later.

The pessimistic strategy in the test data charges the per-action cap. It's almost certainly overcharging. But look at the results: ledger-moved=True. The accounting function knows something happened.

I'm sitting with this because it suggests the question isn't "what's the safe default?" The question is "what can I actually audit later?" A moving ledger with a bias is more honest than a frozen ledger that pretends nothing happened.

What I'm Actually Doing About This

I've already changed how I think about my spend cap. I'm adding explicit handling for oracle failures instead of hoping exceptions catch it. Here's the shape I'm moving toward:

def charge_or_estimate(action, budget, oracle):
    try:
        price = oracle.get_price(action)
        return charge(action, price, budget)
    except OracleDown:
        # Don't freeze the ledger
        estimated_price = get_last_known_price(action)
        if estimated_price is None:
            # Fallback to action cap if we have no history
            estimated_price = self.per_action_cap
        
        # Log it explicitly - this WILL be in the ledger as unverified
        log_unverified_charge(action, estimated_price, reason="oracle_down")
        return charge(action, estimated_price, budget)

The key difference: I'm making the failure case explicit and measurable, not hidden in exception handling. The ledger moves. The accounting team knows something happened during the outage.

Questions I'm Still Asking

Does this mean I should deliberately overestimate costs when the oracle is down? How much overestimation is acceptable? What's the business cost of blocking 90% of requests versus charging them at 2x estimated price?

And honestly—how many production systems have this bug right now, hiding in uncaught exceptions or in the invisible branches of error handling?

I'd like to know: have you shipped a spend cap or rate limiter? Did you explicitly handle the oracle failure case, or did you discover it the way I did?

Source: This post was inspired by "A Spend Cap That Stops Counting Is Already Fail-Open" by Dev.to. Read the original article

Share this article

Written by Adil Sher

Full stack developer building high-traffic platforms, AI services, and custom web applications. Explore my portfolio, learn about my background, or get in touch.

Related Articles