Skip to main content
All postsAutomation Tools

Salesforce Flow vs Apex: A Decision Framework for Every Automation

Flow can do almost everything Apex can, but "almost" is doing a lot of work in that sentence. Here's the decision framework we use on every Salesforce engagement, plus the seven scenarios where Apex still wins.

Ops Automators
May 24, 2026 9 min read
Part of the guide:CRM Automation: Salesforce & HubSpot Workflows That Pay Back
Cover image for Salesforce Flow vs Apex: A Decision Framework for Every Automation

Salesforce Flow vs Apex is the most-asked question on every Salesforce automation project. The answer matters because choosing wrong creates a system that's either fragile (Flow built where Apex was needed) or unmaintainable (Apex built where Flow would have been fine).

The short version: Flow is the default in 2026. Salesforce has invested heavily in Flow Builder for the last three years, deprecated Workflow Rules and Process Builder, and shipped enough Flow capability that most teams can build 80-90% of their automation declaratively. Apex still wins in seven specific scenarios. The rest of this post explains which is which.

What Each Tool Actually Is

Flow is Salesforce's declarative automation engine. You build it visually in Flow Builder. You don't write code. It runs as part of the Salesforce platform with built-in governance, debugging, and version control.

Apex is Salesforce's proprietary programming language: Java-flavored, runs on the Lightning Platform, full programmatic access to the data model and APIs. You need a developer to write and maintain it.

Salesforce has been consistent for years: build in Flow when you can, drop to Apex when you must. This isn't because Flow is "better" in some abstract sense. It's because Flow can be modified by admins, doesn't require code review or test classes for every change, and is the path Salesforce is investing in for the next decade.

The Decision Framework

For every automation requirement, we walk through five questions in order. The first "yes" tells you whether Flow or Apex.

1. Does this require functionality Flow simply can't do?

If yes → Apex. Examples: complex callouts to external APIs with non-standard authentication, recursive logic that needs to call itself, dynamic Apex (running code that's been generated at runtime), or anything that needs SOAP/Metadata API access.

2. Will this process more than 2,000 records in a single transaction, regularly?

If yes → Apex. Flow has governor limits that hit hard at high volume. A record-triggered flow processing batches of 200 records works fine. The same flow processing batches of 10,000 records will hit DML, CPU, or query limits. Bulk Apex with proper batching handles this cleanly.

3. Is this mission-critical financial or compliance logic?

If yes → strongly consider Apex. Flow is reliable, but Apex with proper unit tests, error handling, and code review is the industry standard for code that touches money or regulatory reporting. The audit trail and rollback story is cleaner.

4. Will this be modified by admins after launch?

If yes → Flow. Apex requires a developer to change. Flow can be updated by a certified admin. For automations that will evolve as the business evolves, Flow lowers the cost of every future change.

5. Is this a simple to moderately complex business process?

If yes → Flow. Record updates, screen-based guided processes, scheduled batch updates, multi-step approvals, email alerts, cross-object updates with branching logic: Flow handles all of it natively.

If you've answered "no" or "doesn't apply" to all five, default to Flow.

The Seven Scenarios Where Apex Still Wins

Even with Flow's expanded capabilities, there are specific cases where Apex is the right call.

1. Complex Callouts and Custom Integrations

Flow's HTTP Callout actions handle straightforward REST calls. Anything involving OAuth refresh tokens, custom authentication schemes, SOAP envelopes, or chained API calls with conditional logic is faster and more reliable in Apex. We've migrated a lot of "we built it in Flow" callouts to Apex once the integration outgrew what the visual builder could express cleanly. Stripe invoicing is the one that triggers this most often, usually the first time a line-item edge case needs a retry.

2. Bulk Data Operations

Anything that processes 2,000+ records regularly. Batch Apex with explicit chunking handles millions of records cleanly. Flow attempting the same hits governor limits.

3. Recursive or Self-Referencing Logic

Calculating hierarchical relationships, walking parent-child trees, or running logic that depends on the result of previous iterations. Apex handles recursion natively. Flow does not.

4. Custom Validation Logic Beyond Validation Rules

When validation requires complex cross-object queries, external lookups, or computed values that change based on user attributes. We've seen teams build elaborate Flow chains for this: the Apex version is usually shorter, faster, and easier to maintain.

5. Performance-Critical Triggers

If you're processing a record update that needs to complete in under 200ms (UI responsiveness, real-time integrations), Apex generally outperforms Flow. Flow has optimization layers but Apex is closer to the metal.

6. Asynchronous Patterns Beyond Scheduled Flow

Future methods, queueable Apex, Platform Events with subscribers. These are programmatic patterns that Flow can partially replicate but not fully replace. For complex async workflows, Apex is still the toolkit.

7. Test Coverage Requirements for Compliance

Some regulated industries require explicit test coverage for revenue-impacting automation. Apex unit tests are the industry-standard answer. Flow has Flow tests, but the maturity of the ecosystem around Apex testing is still ahead.

The Hybrid Approach (And Why You Probably Want It)

Most of our Salesforce clients run a hybrid architecture: Flow for declarative work, Apex for heavy lifting, and Flow calling Apex when the situation requires.

A common pattern: a record-triggered Flow handles the routing logic, picks up the right configuration values, and then invokes an Apex action via an Invocable Method to do the actual heavy operation (bulk callout, complex calculation, external system update). The admin owns and modifies the Flow. The developer owns and modifies the Apex. Each part stays in its lane.

This is the model Salesforce officially recommends, and in our experience it scales better than any pure-Flow or pure-Apex approach.

Order of Execution Matters

A common bug: building a Flow and an Apex Trigger that both fire on the same record event, then debugging mysterious behavior for a week. Flows fire before Apex triggers in the order of execution. Apex triggers can fire multiple times per transaction. If both touch the same fields, you can get unexpected results.

Two rules:

  1. One source of truth per field. Decide in design whether a field is owned by Flow or by Apex. Don't have both updating the same field on the same event.
  2. Document the order of execution for any complex automation. We use a simple sequence diagram in the design doc, when this event fires, which flows and triggers run, in what order.

Common Mistakes We See

Flow-everywhere because "no code is better." No code isn't always better. A 47-element Flow doing what 30 lines of Apex would do is harder to maintain, not easier.

Apex-everywhere because "developers want to code." Equally bad. Apex you can avoid is technical debt waiting to compound. Use Flow for admin-maintainable automation.

No naming or governance conventions. Both Flow and Apex grow into unmanageable thickets without naming conventions, ownership documentation, and quarterly cleanup. Build the convention before you build the third automation.

No test environments. Both Flow and Apex should be built in a sandbox, tested, and deployed via change sets or Salesforce DX. Editing production directly is the fastest path to a 2 AM rollback.

The one-sentence test

If you can state the requirement in one sentence and the data volume is reasonable, build it in Flow. If you can't describe the logic without saying "loop," "recursive," "callout," or "bulk," you're probably in Apex territory.

The framework assumes you get to choose

Most of the time you don't.

What you inherit is an org where one field gets written by a Process Builder whose owner left two years ago, by two record-triggered Flows that both fire on update, and by a trigger whose test class only passes because someone commented out an assertion to force a deployment through. The question stops being Flow or Apex. It becomes which of the four things currently writing to that field gets to keep doing it.

So do the inventory before you apply the framework. Every active Flow, Process Builder, Workflow Rule, and trigger, listed against the object and the specific fields each one writes. It takes an afternoon, and it's consistently the highest-value afternoon of a Salesforce cleanup, because "why did this record change" stops being a week of guessing. The messy orgs we inherit are messy for the same reason most implementations fail: nobody ever picked. Automation got bolted on as it occurred to people, year after year, and nothing was ever retired.

Then run the five questions against what's left. If the inventory turns up more automation on a single object than anyone on the team can explain out loud, that's the moment to get help rather than the moment to add a twelfth Flow. We do that pass as fixed-scope work.

Want us to automate this for you?

Request a call: no pressure, no commitment.