A surgeon has a protocol for “stop, that’s wrong” mid-operation. A bank transfer that debits one account and crashes before crediting the other gets rolled back — the whole thing or nothing. We’ve handed agents the power to act on the real world with the same stakes, and given them none of that machinery. An agent that’s booked the flight, charged the card, and then fails to reserve the hotel doesn’t un-book the flight. It just stops, holding a mess.
The model got the glory; the execution layer got ignored. We obsess over reasoning traces and tool schemas, then wire those tools to production systems with no commit, no rollback, no idempotency — the exact guarantees databases spent fifty years getting right. Agent reliability isn’t only a smarter-model problem. It’s a transactions problem.
01Three ways a missing undo button bites
Long agentic runs fail in three distinct ways once they touch the world. Each maps to a database guarantee we simply never gave them.
1. One failure poisons the whole run (no atomicity)
Chain twenty tool calls with no transaction and the run is all-or-nothing in the worst sense: it only fully succeeds if every step succeeds, and per-step failure compounds. At a 5% failure rate, a 20-step run finishes clean barely a third of the time. There’s no “commit the good steps, retry the bad one” — because nothing defined a unit of work to commit.
› Go deeper: why length is the enemy
Per-step success multiplies. A run of L steps that each work with probability p succeeds end-to-end with probability pL — an exponential decay in length. At p = 0.95, ten steps is 60%, forty steps is 13%, eighty steps is under 2%. The model didn’t get worse; the run got longer, and without checkpoints every extra step is another independent chance to throw the whole thing away.
2. Retrying without rollback corrupts state (no idempotency)
So you add retries — the obvious fix, and it does help the run finish. But a tool call that already half-executed before erroring isn’t safe to just run again. Retry “send payment” after a timeout and you may have paid twice. The run reports success; the world is now wrong. Finishing is not the same as being correct.
› Go deeper: the silent-corruption tax
This is the failure mode nobody puts on a dashboard. A crashed run is loud — you see the stack trace. A run that retried a non-idempotent action and quietly double-booked, double-charged, or double-emailed reports green. The cost doesn’t show up in your success rate; it shows up in support tickets a week later. Idempotency keys (a unique token per logical action, so a replay is a no-op) are the cheap, decades-old fix — and almost no agent tool wrapper uses them.
3. There’s nothing to undo with (no compensation)
Even when you detect that a run went bad, what do you do? Real side-effects — an email sent, a row deleted, a charge made — can’t be wished away by clearing context. You need an explicit compensating action for each step: refund the charge, recall the message, restore the row. Without that inverse operation defined up front, “roll back” is just a word.
› Go deeper: the saga pattern, borrowed from microservices
Distributed systems hit this wall years ago: you can’t hold a database lock across twelve services for ten minutes. The answer was the saga — a sequence of local transactions, each paired with a compensating transaction that semantically undoes it. If step 7 fails, you run the compensations for steps 6…1 in reverse. It’s not a true rollback (the email was sent), but a deliberate, defined “undo” for each action. An agent that touches the world needs exactly this: every tool ships with its inverse.
02Borrow the guarantees databases already wrote
The reassuring part: none of this is new. Atomicity, idempotency, durable checkpoints, and compensation are bread-and-butter in transaction processing and distributed systems. Each maps cleanly onto an agent that uses tools.
| Guarantee (DB / systems) | Why it works | The agent move | What it prevents |
|---|---|---|---|
| Checkpoint & resume | Commit good work so a failure costs one step, not the run | Persist state after each step; retry from the last checkpoint | Exponential collapse with run length |
| Idempotency keys | A replayed action becomes a safe no-op | Attach a unique key per logical action; dedupe on the tool side | Double-charges and double-sends on retry |
| Compensating actions (saga) | Every step ships with its semantic inverse | Define undo(step) for each tool; run them in reverse on failure | Partial side-effects with no way back |
| Write-ahead log | Record intent before acting, so you can recover either way | Log the planned call before executing; reconcile on restart | “Did that step actually happen?” ambiguity |
| Dry-run / shadow mode | Validate the plan before it touches anything real | Simulate side-effects first; commit only the validated plan | Acting on a plan that was never going to work |
| Two-phase commit on the risky bit | Prepare-then-commit gates irreversible actions | Gate irreversible tools (pay, delete, send) behind a confirm phase | Irrecoverable actions fired mid-plan |
03I simulated it — and you can run it live
To isolate the execution layer from model quality, I built a Monte-Carlo simulation of an L-step agent where each step fails independently. The model is held fixed; only the recovery machinery changes. Then we ask the question that actually matters: did the run finish AND leave the world in a correct state?
- No-undo — no retries. Correct only if every step works first try.
- Retry-only — retry each failed step, but no rollback, so a retried non-idempotent step can corrupt the final state.
- Checkpoint + compensation — retry from the last checkpoint and undo partial side-effects. Finishes and stays correct.
10 steps No-undo 44% | Retry 64% | Checkpoint 100%
40 steps No-undo 4% | Retry 16% | Checkpoint 100%
80 steps No-undo 0% | Retry 3% | Checkpoint 100%
Two things jump out. First, no-undo doesn’t degrade gracefully — it falls off a cliff, hitting zero by 80 steps purely because length compounds failure. Second, and more important: retry-only is a trap. It looks like a fix — the run finishes far more often — but every retried non-idempotent step is a coin-flip to corrupt state, so “finishes AND correct” plateaus far below 100% and the gap is invisible from inside the run. Only checkpoint-plus-compensation gives you both. The model was identical in all three. The execution layer was the whole story.
Break my assumptions
Every slider re-runs the Monte-Carlo on the spot. Push the failure rate up, or the corruption rate down, and watch where retry-only stops being good enough.
› Go deeper: exactly what the simulation does
Each of the L steps fails independently with probability f. No-undo takes no retries, so the run is correct only if all L steps pass first try — that’s (1−f)L. Retry-only retries each step up to R times (so a step dies only if it fails R+1 times in a row); but any step that needed a retry leaves a corrupting partial side-effect with probability c, and there’s no rollback to clean it — so “correct” requires finishing and never corrupting. Checkpoint has the same retry success but compensation removes the corruption, giving (1−fR+1)L. The in-browser version runs up to 6,000 trials/point; the Colab notebook runs 40,000 for the figure — identical logic.
04Where transactions still won’t save you
Borrowing the database playbook is powerful, not free. Three honest limits:
· Some actions have no inverse. You can refund a charge, but you can’t un-send a leaked secret or un-delete what’s already gone downstream. Compensation handles the reversible majority; the truly irreversible tail needs a hard human gate, not a clever undo.
· Writing compensations is real work — and they can fail too. Every tool now needs a tested inverse, and the compensating action itself can error mid-rollback, which is its own gnarly recovery problem. This is engineering the “just add memory” crowd is hand-waving past.
· Checkpoints can preserve a poisoned state. If a step “succeeds” but commits subtly wrong data, resuming from that checkpoint faithfully carries the error forward. Transactions guarantee consistency, not correctness of intent — a confidently wrong plan checkpoints just fine.
The takeaway
Stop grading agents only on whether they finish. A long agent that touches the world needs the boring machinery we already built for databases: checkpoints so a failure costs one step, idempotency keys so retries are safe, and compensating actions so “undo” is real. None of it is novel research — it’s just unglamorous, and we skipped it.
The agent you’ll actually trust in production won’t be the one with the best reasoning trace. It’ll be the one that can take it all back.
Companion piece: We Gave Agents Memory but No Way to Forget — why “memory” that can’t forget makes agents worse, with its own live simulation.
Sources & further reading
The saga pattern · ACID transactions · Idempotency · Two-phase commit · Compensating transactions · τ-bench (agent reliability)