Salesforce Automation: When to Use Apex vs Declarative Tools (2026)
Picture this: your Salesforce org has a mix of Flows built by admins, Apex triggers written three years ago by a developer who’s long gone, and a Process Builder nobody wants to touch. Sound familiar? Choosing the right automation tool isn’t just a technical decision — it shapes how maintainable, scalable, and sanity-preserving your org will be for years.
The short answer: use declarative tools (Flow) by default, and reach for Apex only when Flow genuinely can’t do the job. But the nuance is where most teams get it wrong.
This guide breaks down every dimension of the apex vs declarative decision — capabilities, limitations, team dynamics, and real trade-offs — so you can stop guessing and start building confidently.
Table of Contents
- Declarative vs Programmatic
- What are declarative tools?
- When to go programmatic
- Flow Overview
- Capabilities of Flow
- Limitations of Flow
- Apex Overview
- When Apex is necessary
- Complexity considerations
- Decision Framework
- Complexity assessment
- Maintenance considerations
- Team skills
- Specific Comparisons
- Triggers vs Flow
- Batch vs Scheduled Flow
- Migration Strategies
- Best Practices
- Conclusion + Decision Tree
- FAQ
Declarative vs Programmatic
What Are Declarative Tools?
Declarative tools let you build automation by configuring — not coding. You drag, click, and connect. Salesforce’s primary declarative automation tools in 2026 are:
- Flow Builder (Screen Flows, Record-Triggered Flows, Schedule-Triggered Flows, Platform Event-Triggered Flows, Autolaunched Flows)
- Validation Rules
- Formula Fields
- Approval Processes
Salesforce has officially retired Process Builder and Workflow Rules in favor of Flow. If you’re still running those in production, a migration plan should be on your roadmap.
Declarative tools shine because they’re accessible to admins, upgradeable without deployments in some cases, and easier to audit visually. They also sit within Salesforce’s governor limits in a more forgiving way for straightforward operations.
When to Go Programmatic
Apex — Salesforce’s proprietary Java-like language — enters the picture when you need precision, performance, or capabilities the UI simply doesn’t expose. You need Apex when:
- You’re doing complex data transformations that would require dozens of Flow elements and become unreadable
- You need fine-grained control over DML operations and governor limit management
- You’re integrating with external systems using callouts inside transactions (though Flow now supports HTTP callouts)
- You require custom metadata manipulation, dynamic SOQL, or dynamic Apex execution
- Your logic involves multiple related objects in patterns too intricate for Flow’s linear or branching structure
The programmatic vs declarative choice isn’t about pride or preference — it’s about fit.
Flow Overview

Capabilities of Flow
Salesforce Flow has grown dramatically since its early days. As of Spring ’26, Flow can:
- Trigger on record create, update, delete, and “before save” operations
- Call Apex via Invocable Methods (bridging declarative and programmatic)
- Make HTTP callouts to external APIs directly within a Flow
- Loop through collections of records and perform bulk operations
- Create, update, and delete records across multiple objects
- Send emails, post to Chatter, submit approval requests
- Launch subflows for modular, reusable logic
- Use custom labels and custom metadata for configuration-driven behavior
- Run asynchronously using the
Run Asynchronouslypath for after-save operations
In many orgs, Flow now handles 80–90% of automation requirements that used to require Apex.
Limitations of Flow
Flow is powerful, but it has real walls. You’ll hit them if you’re not watching:
Governor limits are less flexible. Flow consumes DML statements and SOQL queries from the same transaction limits as Apex, but you have less control over bulkification. A poorly designed Flow can cause limit exceptions at scale that would be easy to prevent in Apex.
Debugging is harder. Flow’s debug logs are improving, but stack traces for failed flows in production are still less informative than Apex debug logs. Tools like Salesforce Inspector and Flow Analyzer help, but complex flows are still painful to troubleshoot.
Version control is clunky. Flows are stored as metadata, but diff-ing two versions of a Flow XML file is not a pleasant experience. Teams serious about DevOps tend to wrap Flow deployments in strict change management processes.
Subflow and loop performance. Deeply nested subflows and large loops can hit CPU limits. If you’re processing thousands of records with complex logic, Apex’s bulk processing patterns are more efficient.
No direct access to system internals. You can’t access Schema methods, dynamic Apex, or system utilities directly. You need an Invocable Apex wrapper.

Read the complete Salesforce Documentation on Salesforce flow limits and considerations.
Apex Overview
When Apex Is Necessary
Apex isn’t going away — it’s just not the first tool you should reach for. Here’s where it earns its place:
Triggers for complex before/after logic. When your record-save logic involves conditional field updates across multiple related objects, complex calculations, or needs to fire only under nuanced conditions involving aggregate queries, Apex triggers give you full control.
Batch processing at scale. Need to reprocess 500,000 records overnight? Database.Batchable is purpose-built for that. Flow’s scheduled processing can handle moderate volumes, but Apex batch is the right tool for heavy lifting.
Custom REST/SOAP APIs. If you’re exposing Salesforce data to external systems through custom endpoints, you need @RestResource classes. Flow can’t do this.
Complex integrations. Calling external APIs with retry logic, conditional branching based on response codes, and error handling across multiple callouts requires Apex. Flow’s HTTP callout action covers simple cases, but multi-step integration flows need code.
Platform Events at scale. Publishing and consuming platform events programmatically, especially with error handling and replay, benefits from Apex’s flexibility.
Complexity Considerations
One pattern I’ve seen repeatedly in enterprise orgs: a Flow that started simple grows into a 150-element monster over two years of incremental additions. At some point, the maintenance cost of a complex Flow exceeds what well-structured Apex would have cost.
The rule of thumb: if your Flow requires more than 30-40 elements and multiple decision branches that interact with each other, consider whether Apex would be cleaner. This isn’t a hard line, but it’s a useful gut-check.
Complex Apex comes with its own risks. Poorly tested Apex, Apex without proper bulkification, or Apex that makes assumptions about record counts can fail catastrophically. Every Apex class needs test coverage (75% minimum, 90%+ in practice), proper error handling, and clear documentation.
Decision Framework

Use this framework when you’re standing at the fork between Apex and declarative tools.
Complexity Assessment
Ask these questions in order:
- Can Flow handle this natively? Check the latest Flow capabilities before assuming Apex is needed. The platform adds new Flow features every release.
- Would this require more than ~30 Flow elements? If yes, Apex may be cleaner — but first check if the logic can be modularized into smaller subflows.
- Does this require dynamic SOQL, Schema methods, or system utilities? If yes, Apex is required.
- Will this process more than ~10,000 records regularly? If yes, consider Apex batch or the performance implications of Flow carefully.
| Scenario | Recommended Tool |
|---|---|
| Simple field updates on record save | Record-Triggered Flow |
| Send email on opportunity close | Record-Triggered Flow |
| Complex multi-object update with conditions | Apex Trigger |
| Nightly reprocessing of large data sets | Apex Batch |
| Exposing custom API endpoint | Apex REST |
| Simple scheduled updates (< 10K records) | Scheduled Flow |
| Callout to external API (simple) | Flow HTTP Callout |
| Callout with retry logic / error handling | Apex |
| Admin-maintained business rules | Flow |
| Complex algorithmic logic | Apex |
Maintenance Considerations
Ask: who will maintain this after you ship it?
If the answer is “an admin or business analyst,” Flow is almost always the right choice. Admins can read, edit, and troubleshoot a well-built Flow. They cannot debug Apex.
If the answer is “a developer team with Salesforce experience,” Apex becomes a viable option — though even developer teams often prefer Flow for its visual auditability.
The total cost of ownership matters more than the build cost. A Flow that an admin can update in 30 minutes without a deployment is often cheaper over three years than an Apex class that requires a developer, a scratch org, testing, and a deployment window.
Team Skills
Your team’s capabilities are a legitimate input into this decision — not a cop-out. Consider:
- Apex skill level on your team. Junior developers writing complex Apex without strong code review processes create technical debt fast.
- Admin empowerment philosophy. Orgs that want admins to move fast without developer dependencies should bias heavily toward Flow.
- On-call and support model. If production issues happen at 2 AM, who debugs them? Make sure the right people can handle what you’re building.
Specific Comparisons
Triggers vs Flow
This is the most debated comparison in Salesforce development circles.
Record-Triggered Flow (Before Save) runs synchronously before a record is saved and can update fields on the triggering record without an additional DML statement. For straightforward field updates and validation-style logic, it’s cleaner and more maintainable than a trigger.
Apex Triggers give you access to Trigger.old, Trigger.new, all context variables, and the full power of Apex. You can query related records, call other classes, and handle complex conditional logic.
The current Salesforce guidance (and best practice consensus) is: use Flow first, use Apex triggers when Flow can’t handle it. This isn’t about capability — it’s about long-term maintainability.
One important rule: never have both a Flow and an Apex trigger doing related things on the same object. Debugging interaction effects between the two is a special kind of pain. Pick one approach per automation concern.
Batch vs Scheduled Flow
Salesforce Batch Apex (Database.Batchable) processes records in configurable chunks (up to 2,000 per batch). It’s the right choice when:
- You’re processing millions of records
- You need precise control over batch size
- Your logic per record is computationally heavy
- You need robust error handling and retry logic per batch
Scheduled Flow (triggered on a schedule) works well when:
- You’re processing hundreds to low thousands of records
- The logic is straightforward and expressible in Flow elements
- Admin visibility and maintainability matter more than performance optimization
- You want to avoid code deployments for logic changes
For most orgs, Scheduled Flow handles the majority of scheduled automation needs. Batch Apex is the right tool when you’re beyond Flow’s practical limits — typically in the hundreds of thousands of records or with complex per-record processing.
Migration Strategies
If you’re sitting on a mix of legacy Workflow Rules, Process Builders, and old Apex triggers, here’s how to approach modernization:
Step 1: Audit your org. Use the Salesforce Optimizer report and the Flow Migration tool to get an inventory. Understand what’s running, how often, and what objects it touches.
Step 2: Prioritize by risk and value. Don’t try to migrate everything at once. Start with automations that are causing problems — slow performance, frequent errors, or ones that admins can’t modify safely.
Step 3: Migrate Workflow Rules and Process Builder to Flow first. Salesforce provides a built-in migration tool for many of these. Test thoroughly in a sandbox — the automated migration isn’t perfect and requires human validation.
Step 4: Evaluate legacy Apex triggers. Don’t rewrite working Apex just to use Flow. Rewrite only when: the Apex is fragile, poorly tested, actively causing issues, or when a Flow equivalent would be significantly more maintainable.
Step 5: Establish a new-build standard. Document your team’s decision framework (like the one above) so future automation is built with intent, not habit.
Best Practices
Regardless of which tool you choose, these practices keep your Salesforce org healthy:
One trigger per object. Whether you’re using Apex triggers or Flow, avoid multiple conflicting automations on the same object. Use a handler pattern in Apex or organize flows by functional area.
Bulkify everything. Both Apex and Flow can fail at scale if you’re not thinking about bulk operations. Test with DataLoader or a script that inserts 200+ records at once.
Document your automation. A Flow or Apex class without comments explaining the business logic is a liability. Write descriptions in Flow, write comments in Apex.
Version control your metadata. Use Salesforce DX (SFDX) and a CI/CD pipeline. Flows as XML in a Git repo means you have history, diffs, and rollback capability.
Test before you deploy. Apex requires 75% test coverage — aim for 90%+ with meaningful assertions, not just coverage. Flows need manual testing and increasingly can be tested with automated testing tools.
Review governor limits proactively. Don’t wait for a production error to discover you’re hitting SOQL query limits. Test with realistic data volumes.
Don’t mix automation paradigms on the same object. Decide: is this object managed by Flow or by Apex? Mixing creates debugging nightmares.

Read our detailed article on salesforce governor limits guide.
Conclusion + Decision Tree
The “apex vs declarative” debate has a clear answer for 2026: start with Flow, escalate to Apex only when needed.
Salesforce has invested heavily in Flow’s capabilities, and in most scenarios, a well-built Flow is faster to build, easier to maintain, and more accessible to your whole team than Apex.
But Apex is irreplaceable for complex logic, high-volume batch processing, custom APIs, and scenarios where code clarity beats visual design. Knowing when to use each tool is what separates good Salesforce architects from great ones.
Quick Decision Tree
Does Flow natively support this use case?
├── YES → Use Flow
│ ├── > 30 elements or deeply nested logic? → Consider Apex
│ └── Admin needs to maintain it? → Definitely Flow
└── NO
├── Complex multi-object logic / dynamic SOQL? → Apex Trigger
├── Bulk processing > 50K records? → Apex Batch
├── Custom API endpoint? → Apex REST
├── Complex external callout with retry? → Apex
└── Simple external callout? → Flow HTTP Callout
Use this framework as your starting point, adapt it to your org’s context, and revisit it as Salesforce releases new features each season. The right tool today might not be the right tool in two releases.
FAQ
Q: Should I always use Flow over Apex in Salesforce? Salesforce recommends Flow as the default automation tool, but Apex is necessary for complex logic, high-volume processing, custom API endpoints, and scenarios requiring dynamic SOQL or system utilities Flow can’t access. Use Flow by default; reach for Apex when Flow genuinely can’t handle the requirement.
Q: Is Apex being deprecated in Salesforce? No. Apex is not being deprecated. Salesforce continues to invest in both Apex and Flow. The platform recommends using declarative tools where possible, but Apex remains essential for complex, code-level requirements. Salesforce has deprecated Process Builder and Workflow Rules — not Apex.
Q: Can Flow replace Apex triggers completely? For many simple to moderate automation scenarios, yes. Record-Triggered Flows (especially Before Save flows) handle a large percentage of what Apex triggers used to do. However, complex triggers involving dynamic queries, multi-object logic, or advanced error handling still benefit from Apex.
Q: When should I use Apex Batch vs Scheduled Flow? Use Scheduled Flow for straightforward operations on up to tens of thousands of records where admin maintainability matters. Use Apex Batch when processing hundreds of thousands or millions of records, or when each record requires complex logic with precise governor limit management.
Q: How do I choose between Apex and Flow when my team has limited Apex skills? If your team lacks strong Apex skills, bias toward Flow. A well-built Flow is maintainable by admins, auditable visually, and doesn’t require a developer for changes. Only introduce Apex when the business requirement genuinely can’t be met declaratively — and ensure you have adequate code review and test coverage practices in place.
Q: What’s the best way to handle both Flow and Apex on the same object? Avoid it where possible. If both exist, clearly document which tool handles which concern and ensure there’s no overlapping logic. Use naming conventions and org documentation to make the separation explicit. Testing interaction effects between Flow and Apex on the same object requires careful scenario planning.
Q: What happened to Process Builder and Workflow Rules? Salesforce officially retired Workflow Rules and Process Builder in 2025. New automations cannot be created with these tools, and Salesforce strongly recommends migrating existing automations to Flow. The built-in migration tool handles many common patterns automatically, but migrations should be validated thoroughly in a sandbox.
Ready to Audit Your Salesforce Automation?
If you’re unsure where your org stands on the Flow vs Apex spectrum, start with a Salesforce Optimizer report. It surfaces your existing automations, flags potential issues, and gives you a baseline for prioritizing your modernization work.
Have a specific automation challenge you’re trying to solve? Drop your scenario in the comments — happy to talk through the right tool for the job.