With salesforce making Salesforce Flow stronger and stronger every release, It’s important to make an informed decision on which Automation tool will be most effective for the solution you are designing for the business requirement.
In seasonal release of Spring 2020, Salesforce releases before-save flow triggers followed by after-save flow triggers in Summer 2020 release. With that Salesforce officially recommended Flow and Apex as No-code and Pro-code preferred options for record triggered automation on their platform
Let’s review which tools salesforce recommends and rational for the most appropriate automation tool on the platform for various use cases.
Before-Save Flow Trigger | After-Save Flow Trigger | After-Save Flow Trigger + Apex | Apex Triggers | |
---|---|---|---|---|
Same-Record Field Updates | Available | Not Ideal | Not Ideal | Available |
High-Performance Batch Processing | Available | Not Ideal | Not Ideal | Available |
Cross-Object CRUD | Not Available | Available | Available | Available |
Complex List Processing | Not Available | Not Available | Available | Available |
Fire & Forget Asynchronous Processing | Not Available | Not Available | Available | Available |
Other Asynchronous Processing | Not Available | Not Available | Not Available | Available |
Custom Validation Errors | Not Available | Not Available | Not Available | Available |
- Available = should work fine, with basic considerations.
- Not Ideal = possible, but with important and potentially limiting considerations.
- Not Available = no plans to support in any capacity in the next twelve months.
Workflow Rule, Process Builder & Salesforce Flow
While salesforce announced that they are not discontinuing Workflow rules or Process builder anytime soon they will be deprecated flow. Therefore will no longer receive any performance, Debugging, Manageability or CI/CD improvements.
Workflow Rules:
The majority of workflow rules are known for the Same record field updates and being fast. They nevertheless cause a recursive save and will always be considerably slower and more resource-hungry than a single functionally equivalent before-save Flow trigger.
Process Builder:
Process builder in fact runs on top of flow’s runtime, However, there is a vast difference between Process Builder’s user-facing design-time model and the Flow runtime’s metadata model. Process builder will always be less user-friendly and has a list view that doesn’t allow any filters or modification which makes it more difficult to manage process.
For this reasons, Salesforce recommends, Building with Flow where possible, and resorting to Process builder or workflow when necessary.
Compare Performance between different automation tools
This performance discussion is around the Same record field update use case. While Workflow Rules have a reputation for being fast, they nevertheless cause a recursive save and will always be considerably slower and more resource-hungry than a single functionally equivalent before-save Flow trigger.
Before-save Flow triggers neither causes DML nor the ensuing recursive firing of the save order, while Workflow Rules do because they happen after the save.
Based on this theory, a couple of experiments were performed by salesforce to compare the processing time and CPU usage
Experiment 1: Apex Debug log duration for Single Triggered single record creation through UI by User
User’s wait time comparison for the same action (Record creation) using different automation tool (Workflow/Process Builder/ Salesforce flow)
- Except for the baseline org, implemented the simplest version of a trigger on
Opportunity Create
that would setOpportunity.NextStep = Opportunity.Amount
. - Enabled Apex debug logging, with all debug levels set to
None
exceptWorkflow.Info
andApex Code.Debug
- Manually created a new Opportunity record with a populated Amount value through the UI, 25 times.
- Calculated the average duration of the log across the 25 transactions.
- Subtracted from the average duration in #4, the average duration of the log in the baseline org.

Experiment 2: 50 triggers; 50,000 records inserted via Bulk API (200 record batches); internal tooling
How about the other side of the spectrum: high-volume batch processing?
We borrowed some of our performance team’s internal environments to get a sense of how well the different trigger tools scale.
The configuration was:
- 1 org with 50 before-save Flows on
Account Create
which each updateAccount.ShippingPostalCode
- 1 org with 50 before-save Apex triggers on
Account Create
which each updateAccount.ShippingPostalCode
- 1 org with 50 Workflow Rules on
Account Create
which each updateAccount.ShippingPostalCode
- 1 org with 50 after-save Flow triggers on
Account Create
which each updateAccount.ShippingPostalCode
- 1 org with 50 Process Builder processes on
Account Create
which each updateAccount.ShippingPostalCode
Then each Tuesday for the last 12 weeks, we uploaded 50,000 Accounts to each org through the Bulk API, with a 200-record batch size.
Fortunately, our internal environments can directly profile trigger execution time without requiring Apex debug logging or extrapolation from a baseline.
Unfortunately, our internal environments are so ill-representative of production that we’re only allowed to present the relative performance timings and not the raw performance timings.

As you ca see from the above chart, In both single-record and bulk use cases, the before-save Flow performs extremely well.
CPU Usage
CPU time reported in apex debug log is inconsistent at the moment, which salesforce reported as issue with reporting and not with measurement issue.
For example, if a Flow consumes 8s actual CPU time during runtime, then the cumulative Governor CPU time limit will be incremented by 8s. However, the Flow element-level contributions to the limit, which are displayed in the Apex debug logs, are not always properly attributed. Sometimes, CPU time that should have been attributed to a Flow element is not attributed to any element in the Flow. As a result of this misattribution, the sum of the attributed element costs will not always equal 8s; instead, they may add up to a number that is less than 8s. In this case, the difference will be unintentionally rolled into the next CPU time consumption line in the debug logs. Salesforce is planning to fix this in upcoming release.
In the meantime, a Flow’s CPU time consumption can be upper-capped by its wall clock time consumption. This is because Flows run on a single thread.