Why Good Bots Never Buy Twice

Here's a failure that finds every automated buyer eventually: the script buys three of your five cases, the marketplace API times out, the run dies. Now what? If re-running the script means buying those three cases again, you don't have automation — you have a machine that punishes you for its own crashes.

Why Good Bots Never Buy Twice
Why Good Bots Never Buy Twice · source: alphr.com

Idempotency, in plain words

An operation is idempotent if doing it twice has the same effect as doing it once. A light switch labeled "on" is idempotent — flip it again, the light is still just on. A button labeled "add one more" is not. Payment engineers live and die by this distinction, which is why your card doesn't get charged twice when a checkout page glitches and you hit refresh.

For a skin-buying bot, the idempotency question is concrete: "buy today's list" must mean "make sure today's list has been bought" — not "issue today's purchase commands again." The first phrasing is safe to run any number of times. The second is a hazard with a scheduler attached.

Why re-runs happen constantly

You might think a daily script runs once a day and that's that. In practice, re-execution is routine, not exotic:

  • A marketplace API times out mid-run and the process exits halfway through the list.
  • The cloud scheduler misfires and triggers the job twice — scheduling in the cloud is messier than the word "cron" suggests, and most schedulers explicitly promise "at least once," not "exactly once."
  • You deploy a config change at noon and restart the job to pick it up.
  • You're debugging, so you run it by hand. Twice, because the first output scrolled past.

A non-idempotent bot converts every one of those mundane events into duplicate spending. And the cruel part is the incentive it creates: when a run fails halfway, the safest move becomes doing nothing, because intervening might double-buy. Your "automation" now requires more careful human supervision than buying manually did.

The ledger is the fix

The standard solution is quietly elegant: make the purchase ledger the source of truth, and make the bot read it before it spends. Every completed purchase is recorded — item, quantity, price, timestamp, which plan it belonged to — in the same breath as the purchase itself. At the start of every run, the bot loads today's ledger lines and subtracts them from today's intentions.

Now walk the crash scenario again. The bot buys cases one through three, records each, and dies on number four. You re-run it. It reads the ledger, sees three fills already stamped with today's date, and plans a run consisting of exactly the two missing items. Run it a third time after that and it plans nothing at all — a clean no-op with a log line saying so. The dangerous question ("did the first run finish?") stops mattering, because the re-run is the recovery procedure. This is how cs2stack behaves, and it's also why its standing orders — "buy one of this case per week" — count fills from the log rather than trusting a schedule: the ledger, not the clock, decides whether this week's buy already happened. The details are in standing orders as code.

Note what this design does not depend on: the bot's memory of its own run (lost in a crash), the scheduler's honesty (unreliable), or a human checking first (defeats the purpose). Only the written record, which survives all three.

Idempotency is a load-bearing wall, not a feature

Once buys are idempotent, several other guarantees become trustworthy instead of probabilistic. A daily budget cap is only a real cap if a double-triggered run can't spend the budget twice — the cap must be computed against recorded spending, not against each process's private counter. An allocation scheme is only fair if retries don't tilt spending toward whichever items happened to sit early in the list. Even your cost basis quietly assumes no phantom duplicate fills are inflating your position.

This is why idempotency belongs on the short list of non-negotiables when you evaluate any buying tool, alongside hard caps and dry-run modes — the full checklist lives in safety engineering for buying bots. It's also the least marketable item on that list, which tells you something: nobody screenshots a no-op. The vendors who bother with it are the ones who've imagined the failure honestly.

Why Good Bots Never Buy Twice
Why Good Bots Never Buy Twice · source: opengraph.githubassets.com

How to test it in five minutes

You don't have to read source code to check this. Take any bot with a dry-run mode — a mode that plans purchases against real prices without spending — and run it twice in a row. The second run should plan zero new buys for the day, or at minimum show it deducting the first run's planned fills. Then ask the vendor the one-sentence question: "If a run dies halfway and I re-run it, what happens?" The right answer mentions a log or ledger. The wrong answer mentions being careful.

Automation earns its keep by being safe to ignore. A bot that never buys twice is one you can let crash, restart, re-trigger, and walk away from — which is the entire product, really. The buying was always the easy part.