Pattern of the week: Saga with Compensating Transactions

Every automation builder hits this one eventually. A process that touches three systems works fine in testing, then fails halfway through in production. Now the CRM says the customer exists, billing says they don't, and nobody has access to anything. You spend the afternoon fixing records by hand and promising yourself it won't happen again.
It will, unless you design for it. That's what the Saga with Compensating Transactions pattern is for.
The problem
When one business action spans several systems, you don't get a single database transaction to wrap around it. There's no "rollback" button that covers your identity provider, your billing platform and your CRM at the same time. Each system commits on its own. So when step three fails, steps one and two have already happened.
A saga accepts that. Every forward step gets a paired compensating step that undoes it, in business terms. If step N fails, you run the compensations for N-1 back down to 1, in reverse order.
Here it is for a new customer set up across identity, billing and CRM:
Rendering diagram…
When to use it
Reach for a saga when an "all or nothing" process crosses two or more systems that can't share a transaction. Order placement across inventory, payments and shipping. Provisioning a new user across auth, billing and CRM. Creating a contract that also updates finance and access control.
If everything lives in one database, you don't need this. Use the transaction you already have.
My rule of thumb: start with an orchestrated saga, where one workflow knows every step and every compensation. It's far easier to see what happened when something goes wrong. The event-driven, choreographed version scales better, but debugging it is brutal. Move there only when you've outgrown a single workflow engine.
The pitfall: thinking compensation is rollback
This is the one that bites people. A compensation doesn't erase what happened. It reverses it as best it can. You can refund a charge, but the customer still saw it on their statement. You can't unsend a welcome email. You can only send a "sorry, ignore that" one, or decide that's acceptable.
So before you build anything, write the pairs down. For every step: what it does, and what the reverse looks like. If you can't describe the reverse, you don't have a saga. You have wishful thinking.
And plan for the compensation itself to fail. Sometimes the refund call times out too. Make compensations safe to retry (an idempotency key stops a refund from running twice), and give the stuck ones a path to a human. Some failures will always need a person. Better to design that in than to find out at 2am.
The full pattern, with the BPMN flow and a step-by-step implementation guide, is here: Saga with Compensating Transactions.