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 TriggerAfter-Save Flow TriggerAfter-Save Flow Trigger + ApexApex Triggers
Same-Record Field UpdatesAvailableNot IdealNot IdealAvailable
High-Performance Batch ProcessingAvailableNot IdealNot IdealAvailable
Cross-Object CRUDNot AvailableAvailableAvailableAvailable
Complex List ProcessingNot AvailableNot AvailableAvailableAvailable
Fire & Forget Asynchronous ProcessingNot AvailableNot AvailableAvailableAvailable
Other Asynchronous ProcessingNot AvailableNot AvailableNot AvailableAvailable
Custom Validation ErrorsNot AvailableNot AvailableNot AvailableAvailable
  • 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)

  1. Except for the baseline org, implemented the simplest version of a trigger on Opportunity Create that would set Opportunity.NextStep = Opportunity.Amount.
  2. Enabled Apex debug logging, with all debug levels set to None except Workflow.Info and Apex Code.Debug
  3. Manually created a new Opportunity record with a populated Amount value through the UI, 25 times.
  4. Calculated the average duration of the log across the 25 transactions.
  5. 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 update Account.ShippingPostalCode
  • 1 org with 50 before-save Apex triggers on Account Create which each update Account.ShippingPostalCode
  • 1 org with 50 Workflow Rules on Account Create which each update Account.ShippingPostalCode
  • 1 org with 50 after-save Flow triggers on Account Create which each update Account.ShippingPostalCode
  • 1 org with 50 Process Builder processes on Account Create which each update Account.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.

Bar chart showing average time added to bulk record updates from most to least efficient tool.

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.