Salesforce Dictionary - Free Salesforce GlossarySalesforce Dictionary
All articles
Development·May 3, 2026·10 min read

Salesforce Flow vs Apex in 2026: A Decision Matrix for Admins, Developers & Consultants

Side-by-side capability table, governor-limit comparison, 12 real-world scenarios, and the 70/30 rule that ends the argument.

Salesforce Flow vs Apex 2026 — a decision matrix

TL;DR

  • Flow is your default for record-triggered automation. It's faster to ship, easier for admins to maintain, and Salesforce is investing in it heavily.
  • Apex is the right tool when you need recursion control, complex iteration, async patterns beyond what Flow exposes, callouts inside transactions, or anything performance-sensitive at scale.
  • The 70/30 rule: Most teams should land roughly 70% Flow, 30% Apex. If you're 95% one or the other, something is off.
  • The combo move: Flow as the orchestrator + invocable Apex for the heavy lifting. Best of both worlds for ~80% of complex work.

The "Flow vs Apex" debate is the longest-running culture war on the Salesforce platform. It used to matter — early Flow had real performance gaps. In 2026, the two tools live alongside each other, and the question isn't which but when.

This guide gives you a concrete decision framework: a side-by-side capability table, a governor-limits comparison, twelve specific scenarios with the right answer for each, and the pattern senior consultants use to combine the two.

Decision tree: when to pick Flow vs Apex vs combine the two

Side-by-side capabilities

CapabilityFlowApex
Built byAdmins (and devs)Developers only
DeploymentMetadata API, Change Set, DevOps CenterSame — plus mandatory test coverage
RuntimeDeclarative interpreterCompiled Apex VM
Source controlYAML/XML, large diffsCode, clean diffs
Async patternsScheduled paths, async actions, Subflow@future, Queueable, Batch Apex, Schedulable, Platform Events
Recursion controlLimited (entry conditions, "only when updated to meet criteria")Full — static counters, recursion guards
CalloutsYes, but only outside the transactionYes, in callout-allowed contexts
Test coverageOptional Flow tests (recommended)Required ≥ 75%
Speed for simple writes~2-3× slower than Apex but trivial casesAlways fastest
Speed for complex iterationSignificantly slower than ApexFastest
DebuggingFlow Debug + replay; new in 2026Apex log levels, checkpoints, debugger
Discoverability for non-devsExcellentPoor
Refactoring toolsLimited (manual extraction)Excellent (IDE refactors)

Governor limits — the comparison that matters

Both tools share the same per-transaction governor limits — they're enforced at the platform layer, not the tool layer. But how each tool consumes them differs.

Governor limits: Flow vs Apex consumption patterns

  • SOQL queries. Flow's "Get Records" element is one query. Loops can multiply queries dangerously if you're not careful — every iteration that fetches records is its own SOQL call. Apex with proper bulk patterns puts queries outside loops by design (or by code review).
  • DML statements. Flow's "Update Records" inside a loop is a classic anti-pattern. Apex's upsert myList is a single DML. Bulkify Flow with collection variables to match Apex's behavior.
  • CPU time. Per transaction, default is 10,000ms sync / 60,000ms async. Flow uses CPU more liberally for the same work — expect 1.5–3× the CPU consumption of equivalent Apex. For high-volume triggers, this matters.
  • Heap size. 6MB sync / 12MB async. Flow's collection variables are slightly heavier than Apex collections. Rarely a constraint unless you're materializing tens of thousands of records.

The simple rule: Flow is fine until you're hitting limits. When you're hitting them, Apex gives you the precise control you need to fix it.

The 70/30 rule

Most production-quality Salesforce orgs land roughly 70% Flow, 30% Apex over a long enough timeline. The split skews differently by team:

  • Heavy customer service org → 75% Flow, 25% Apex (lots of declarative case routing).
  • Heavy revenue/commerce org → 60% Flow, 40% Apex (CPQ, integrations, complex pricing).
  • Industries Cloud / OmniStudio org → ~50/50 with OmniStudio sitting in the middle.

If you're 95% Flow, you're probably doing things in Flow that should be Apex — and you'll feel it in maintenance pain and CPU limits. If you're 95% Apex, your admins can't help maintain the platform and your time-to-deliver is too slow.

Twelve scenarios with the right answer

For each, the recommended primary tool — and when to consider switching.

#ScenarioPickWhy
1Update child records when a parent flag flipsFlowClassic before-save / after-save Flow
2Send an email when a Case is escalatedFlowSend Email action covers it
3Round-robin assignment to a QueueFlow with optional ApexFlow for the orchestration; Apex for state if scale is high
4Recalculate a complex roll-up across non-master-detail relationsApexBeyond Flow's roll-up element capabilities
5Nightly batch to dedupe 5M recordsBatch ApexVolume + chunking — Flow is wrong tool
6Webhook-triggered downstream workFlow with Apex calloutPlatform Event → Flow + Apex helper
7Create a Case from inbound email parsingApex (Email Service)Parsing logic + reliable threading
8Launch an Agentforce ActionEitherBoth expose as agent Actions; pick by tooling preference
9Bulk update on Account hierarchy traversalApexRecursive walks are painful in Flow
10Approval routing with conditional stepsFlowApproval Process or Flow with branches
11Generate a PDF doc and attach to a recordApexRendering libraries + buffer handling
12"When Opportunity reaches stage X, create 3 child tasks"FlowTrivial declarative case

The combination pattern: Flow + invocable Apex

The single most-used pattern in mature orgs.

Flow as orchestrator, invocable Apex as the heavy-lifting unit

public with sharing class CalculateChurnRiskAction {
  @InvocableMethod(label='Calculate churn risk' callout=false)
  public static List<Result> calculate(List<Request> requests) {
    List<Result> results = new List<Result>();
    for (Request r : requests) {
      Decimal score = ChurnModel.scoreFor(r.accountId);
      results.add(new Result(score));
    }
    return results;
  }
  public class Request {
    @InvocableVariable(required=true) public Id accountId;
  }
  public class Result {
    @InvocableVariable public Decimal score;
    public Result(Decimal s) { score = s; }
  }
}

In Flow, drop a single "Action" node referencing CalculateChurnRiskAction, pass the Account Id, get a Decimal back. Flow drives the orchestration (when to fire, what to do with the result, where to write); Apex handles the iteration, recursion, or whatever's hard.

When to reach for this pattern:

  • You need a tight loop or recursion (Flow loops scale poorly).
  • You need transactional control (rollback semantics, savepoints).
  • You're calling an external service.
  • You need code-level test coverage on critical math.
  • The logic is genuinely hard and would be 40 nodes in a Flow no one can read.

What changed in Spring '26 + Summer '26

Three Flow features worth knowing about, all of which narrow the historical Flow-vs-Apex gap further.

  1. Inline expressions in record-triggered Flows. You can now write a small expression directly inside a Flow element instead of building three Formula resources. Saves nodes; makes Flows readable.
  2. File-attach trigger. Flows now fire on ContentVersion insert, not just standard objects. This kills a common Apex Trigger use case (auto-classify uploaded docs).
  3. Async path step preview. Flow Builder now shows the actual async-path execution timeline in test runs, so you can see when each scheduled path will fire. Previously you had to deploy and wait.

On the Apex side: TypeScript-flavored Agent Script (covered in our Agentforce 360 guide) is the biggest 2026 change for developers. It doesn't replace Apex but adds a new authoring surface.

Common mistakes (and the fix)

  • "All Flow" stance from leadership. It comes from a real desire to enable admins. The result is unmaintainable mega-Flows that nobody on the team can debug. Push back with the 70/30 framing.
  • Skipping Flow tests. Test classes are mandatory for Apex. Flow tests are optional but you should treat them as required for any production-bound Flow. The discipline pays back.
  • Inline Apex from Flow without bulk handling. Always design @InvocableMethod to accept a List<Request> and process in bulk — even if Flow is calling it one record at a time today. Future-proof.
  • Stopping the Workflow RuleProcess Builder → Flow migration. With Workflow Rules and Process Builder fully retired by end of 2025, anything still running on them in 2026 is on borrowed time. Use Migrate to Flow — see our migration playbook when it lands.

Frequently asked questions

Is Flow getting deprecated? The opposite. Flow gets more investment than Apex year over year. Salesforce wants more admins building automation directly.

Is Apex getting deprecated? Also no. Apex remains the only option for many use cases (callouts mid-transaction, complex iteration, real OOP). It's the foundation for Agentforce Actions too.

Should I rewrite my old Apex Triggers as Flow? Generally, no. If they work, leave them. Migrate Workflow Rules and Process Builders, not stable Apex.

Which is better for testing? Apex testing is more mature and the platform requires it. Flow testing is good now but optional. For mission-critical paths, the Apex test discipline still wins.

My team disagrees on the 70/30 rule. What do we do? Track real outcomes for two release cycles. Count: Flows that needed Apex bailouts, Apex that should have been Flow, average time to ship a feature. Numbers end the argument faster than opinions.

If you only take one thing from this guide: Flow first, Apex second, combine when stuck. Most automation arguments in 2026 dissolve when you apply that order in writing.

Share this article

Sources

Related dictionary terms

Keep reading