Skip to main content
New tool CRON Expression Builder — preview next run times before you schedule Apex. Open the builder →
Diagram illustrating Salesforce Flow transactions and rollback process boundaries for developers
Flow

How to manage Salesforce Flow transactions and rollbacks

Ever had a flow crash and roll back changes you actually wanted to keep? That comes down to where the transaction boundaries sit. Here is how to handle rollbacks and keep your data clean without the Sunday night panic.

If you have ever spent a Sunday night fixing data because a process crashed halfway through, you know how tricky Salesforce Flow transactions get. It looks simple until a complex record-triggered flow starts hitting governor limits, or rolls back changes you actually wanted to keep.

Understanding Salesforce Flow transactions and boundaries

Salesforce works on an "all or nothing" basis. When a Flow starts, it joins a transaction. If anything goes wrong and you do not handle the error, Salesforce rolls the whole thing back. That is usually good, because it prevents partial data, and it is a massive headache when you are trying to debug what actually happened.

I have seen teams struggle here because they do not know where the transaction starts and ends. A "before-save" flow is basically part of the record's initial save. It does not do its own DML, so it is very fast. An "after-save" flow is a different beast: it runs in the same transaction as the initial save, which means that if your flow fails, the record that triggered it does not get saved either. There is more on ensuring data integrity if you want the wider picture.

  • Synchronous flows run right now, in the same bucket of resources as whatever started them.
  • Asynchronous paths happen later, in their own separate transaction. That is your friend when you need to do something heavy like calling an external API.
  • A Pause or Wait element ends the current transaction and commits it. When the flow resumes, it is a brand new transaction.

Pro tips for managing Salesforce Flow transactions

So how do you actually control this behavior? Most teams stop at the default "unhandled exception" email, which tells you something broke and almost nothing about what to fix. Be deliberate about how you handle failures and where you break the work into smaller chunks.

1) Make fault paths write something down

Every DML element (Create, Update, Delete) has a Fault connector. Use it, and make it do more than show a screen saying "Oops." I always recommend logging the error to a custom "Error Log" object. Even when the main transaction rolls back, a Platform Event can sometimes publish that log so it stays in the database. It is also worth looking at error handling for specific actions like emails.

In my experience, the biggest mistake people make is assuming a Fault Path fixes everything. If your Fault Path does not lead to a screen or a log record, you are still flying blind when things go sideways.

2) Decouple risky work

If a piece of logic is likely to fail, like an integration call or a complex calculation, do not let it kill your main transaction. Platform Events or asynchronous paths move that work into a separate Salesforce Flow transaction, which keeps the primary record update safe when the secondary stuff fails. This guide on when to use different asynchronous types covers which tool to pick.

3) Invocable Apex and savepoints

Sometimes Flow is not enough and you have to call Apex. You can use Database.setSavepoint() and Database.rollback() in your code, but be careful. These savepoints apply to the whole transaction: if you roll back in Apex, you are rolling back everything the Flow did up to that point too. It is a powerful tool, and a bit like using a sledgehammer to hang a picture frame. Use it only when you have a very specific reason.


public class FlowAsyncProcessor {
    @InvocableMethod(label='Run Heavy DML')
    public static void runAsync(List<Id> recordIds) {
        // Enqueueing a job creates a new transaction boundary
        System.enqueueJob(new MyQueueableJob(recordIds));
    }
}

Key takeaways for Salesforce Flow transactions

  • Every element in a single transaction shares the same governor limits. If your Flow is huge, break it up.
  • Fault paths are your safety net. Make them log the error somewhere you can read later.
  • Platform Events suit "fire and forget" logic that should not stop the main process.
  • A Wait element explicitly ends one transaction and starts another, which helps when you are hitting limits.

Wrapping it up

Managing Salesforce Flow transactions comes down to knowing when to stay in the current boat and when to jump into a new one. Map out your transaction boundaries before you build. If you have a lot of DML happening in one go, ask what happens if this fails at step 4. If the answer is a giant mess, it is time to decouple the logic. Log your errors, and use async paths when things get heavy.

Newsletter

One email every Tuesday

New guides, tool updates, and the release-note changes that break things.

No spam. Unsubscribe in one click.

Comments

Loading comments...

Leave a Comment