Automation During the Load
תוכן זה אינו זמין עדיין בשפה שלך.
Also in 19 languages
Español · 日本語 · Português (Brasil) · Français · Deutsch · Italiano · 한국어 · 简体中文 · Português (Portugal) · 繁體中文 · Bahasa Indonesia · Türkçe · Polski · Tiếng Việt · ไทย · Українська · Español (México) · Français (Canada) · Deutsch (Schweiz)

Module 3 of 5 in the chapter Migration and Synchronization, chapter 10 of the Data Architect course. Each module stands on its own. Previous: Loading at Volume · Next: Cutover Weekend
The question this module answers: What should happen to Salesforce automation while migration data is being loaded?
RouteDesk’s records are ready: about 707,000 of them, prepared, sorted by parent, rehearsed. You start the load, and Salesforce starts doing exactly what you configured it to do. Flows fire, triggers run, validation rules evaluate, emails send, tasks get created, rollups calculate, integrations launch, events publish. Your 707,000-record migration isn’t performing 707,000 operations anymore. It’s performing 707,000 records multiplied by everything each record causes. That’s a different migration.
Start With the Picture
Section titled “Start With the Picture”Here’s the landscape again, the weekend RouteDesk retires. The migration arrow is amber. Now look at what else leaves Salesforce when a Work Order is created or changes status.
One arrow in. Three more arrows out, for every record, unless we decide otherwise.
Every one of those arrows was designed in chapter 9 for a delivery that just happened: a status changed, so tell the partner and Snowflake; a delivery finished, so count it for invoicing; a delivery is tomorrow, so text the Recipient. The load creates 196,400 Work Orders in one weekend, and about 190,000 of them arrive already completed. To the automation, each one looks like a delivery that just happened.
Automation Doesn’t Know It’s a Migration
Section titled “Automation Doesn’t Know It’s a Migration”Salesforce sees a record transaction. It doesn’t know “this is historical data loaded during a controlled cutover.” A flow sees a new Account and does what it was built to do: creates an onboarding task, sends a welcome email, publishes an event, updates a related record, calls another system. Correct when a sales rep creates one account on Tuesday afternoon. Completely wrong when a migration creates 800,000 historical accounts on Saturday night. Same operation, different business context. At Steve Trucking, a Work Order arriving with a status of Completed looks exactly like a crew finishing a delivery five minutes ago.
So for a major migration I start from this: normal business automation should not blindly run against the load. That doesn’t mean “turn off everything.” It means every important automation gets a deliberate decision, and I don’t want the answer discovered because production sent 400,000 emails.
Three Choices: Don’t Need It, Simulate It, Defer It
Section titled “Three Choices: Don’t Need It, Simulate It, Defer It”For each automation, I ask what it does and what happens if it doesn’t run, and then I put it in one of three categories.
Don’t need it (eliminate). The behavior shouldn’t happen for migrated records. Customers we’ve had for eight years don’t need “Welcome to our company!” Insert an account, it sends an email; load a million accounts, and I don’t need a million emails.
Simulate it. The automation shouldn’t run, but the result it creates is still required. A flow on account creation derives Customer Segment. Migrated accounts need a valid segment, but running the whole flow five million times is expensive or has side effects. So we calculate the segment in the transformation and load the result. We didn’t ignore the business rule; we did the work of the automation in the load.
Defer it. The result is needed, but not inside the load transaction. Load with the automation off and a flag set, then trigger a batch process to catch up: recalculate, create dependent records, publish what downstream systems need. Deferring can make the load faster and more controllable without giving up the outcome.
And sometimes you leave it on. For a smaller load where the business wants its normal process to run, let the system do what it does. That’s a choice too, as long as it’s a choice.
Whatever you pick, this is the rule I teach: any time you turn an automation off, you’re taking full responsibility for that business logic not happening. You need to understand every automation before you decide.
Three questions, four answers, one decision per automation.
Test knowledge. For each automation on a large load, decide: not needed for migrated data (bypass it), needed but its result can be set in the data (simulate it in the transformation), needed but not inside the load (defer it to a batch afterward), or needed inside the load (let it run). Expect a scenario where blindly running automation creates unwanted emails, tasks or integration calls, and one where turning it off silently loses a required result.
“Disable Automation” Isn’t the Whole Strategy
Section titled ““Disable Automation” Isn’t the Whole Strategy”The plan says “disable the automation.” Which automation? How, who, when? How do we know it’s off, and how do we know it’s back on? Which results it normally produces must still exist afterward? What happens if users are in the system while it’s off, or the migration fails halfway? Turning something off is an operational action. The architecture needs the whole lifecycle: normal state, migration state, return to normal, and proof that we returned.
And before you decide what to switch off, find out what’s still switched on. Old automation runs on migrated records too. Salesforce ended support for Workflow Rules and Process Builder on December 31, 2025, but “your active Workflow Rules and Process Builder processes continue to run as they did before” (Workflow Rules & Process Builder End of Support (opens in a new tab), Salesforce Help, checked 2026-10-27). Well-Architected points out the cost: an org “carrying dozens of Process Builders left over from prior implementations … pays to evaluate every one of them on every relevant record save,” and its advice is to “migrate remaining Process Builders to Flow; don’t just deactivate them” (Resource and Cost Optimization (opens in a new tab), checked 2026-10-27). A migration is a good reason to clear them out first, so 707,000 records aren’t run through automation nobody remembers.
Build the Bypass In From the Start
Section titled “Build the Bypass In From the Start”My stronger position: important automation should have a controlled bypass even when no migration is planned. Migration isn’t the only reason you’ll need one. Large remediation, data correction, backfills, integration repair, emergency recovery: sometimes you have to run a controlled operation without every piece of normal automation. If the only way is to edit the flow in production, deactivate the trigger or delete a validation rule, we’ve made operational work needlessly dangerous. And you can’t simply switch a trigger off in production: that’s a deployment, with its tests.
The standard answer is a bypass (some teams call it a kill switch): the first thing the trigger or flow does is check a switch, and skip itself if the switch is on. Decide the scope: a global switch for the whole org, one per object, one per automation, or one for particular users, such as the data load user or anyone holding a permission. Put it in your flows as well as your triggers. Flows are easy to deactivate, but a user-specific switch lets everyone else keep working. I consider flows visual programming: whether you’re writing code or programming visually, you’re still programming, and programs need this.
And here’s the part teams miss: the bypass is part of the original design. It isn’t something you build the week you need it. Every trigger and flow gets its bypass when it’s first built. It’s tested both ways, switched on and switched off, like any other behavior. And it goes to production with the automation, long before any migration, so on cutover weekend it’s already there, already tested, and ready to switch on. A bypass written in a hurry for the load is new, untested code going into production on the riskiest weekend of the project. Salesforce’s Record-Triggered Automation decision guide is just as firm: “A well-architected Salesforce organization requires a consistent and reliable mechanism to bypass automation. This is not an optional feature, but a core operational requirement” (Record-Triggered Automation (opens in a new tab), Salesforce Architects decision guide, checked 2026-10-27).
Salesforce says the same thing in its own words. Its Well-Architected list of automation anti-patterns includes “Flows must be manually deactivated prior to bulk data loads” (Automation Patterns (opens in a new tab), Operational Excellence, checked 2026-10-27). If your load plan says “deactivate these twelve flows on Friday night,” that’s the anti-pattern.
Test knowledge. Build a bypass into triggers and flows when they’re first built (a check of a custom permission, a custom setting or custom metadata at the start), test it on and off, and deploy it ahead of time, so large loads can skip them without editing or deactivating anything in production. Scope it: by object, by automation, or by user, such as the migration user. Deactivating flows by hand before a bulk load is an anti-pattern in Salesforce’s own Well-Architected guidance.
What a Bypass Looks Like
Section titled “What a Bypass Looks Like”So what does a bypass actually look like? Three parts: a place to keep the switch, a check at the top of every trigger and flow, and the same check in the validation rules you decide to relax. Salesforce gives you three places to keep it, and each one decides who the switch applies to.
| Where the switch lives | Who it applies to | Good for |
|---|---|---|
| A custom permission, granted by a permission set | Only the users who hold it | The usual migration bypass: give it to the migration user for the load, take it away after |
| A hierarchy custom setting | The whole org, one profile, or one user | A global “automation off” for everyone, or a switch for one profile or one user |
| A custom metadata record per automation | Everyone, for that one automation | Switching off one specific automation, deployed and versioned like code |
The hierarchy custom setting is the one that does global, profile and user in one place. Salesforce’s description: it “checks the organization, profile, and user settings for the current user and returns the most specific, or lowest, value” (Define Custom Settings (opens in a new tab), Salesforce Help, checked 2026-10-27). Set it off for the org, on for the migration user, and the migration user gets the bypass while everyone else gets normal automation. For most other configuration Salesforce now steers you to custom metadata instead, which deploys with your code; I’d use that for the per-automation switches.
In Apex, the check is the first thing the trigger does. Here’s what it could look like on the Work Order, with a hierarchy custom setting called Automation_Bypass__c and a custom permission called Bypass_Automation:
trigger WorkOrderTrigger on WorkOrder (after insert, after update) { // The hierarchy custom setting: the user's value, else the profile's, else the org's Automation_Bypass__c settings = Automation_Bypass__c.getInstance();
// Bypass if the setting says so, or if this user holds the custom permission Boolean bypass = settings.Disable_Triggers__c == true || FeatureManagement.checkPermission('Bypass_Automation');
if (bypass) { return; // no side effects; the record still saves }
WorkOrderStatusOut.publish(Trigger.new, Trigger.oldMap);}getInstance() returns the setting “for the current user,” merged from the lowest level that’s defined (Custom Settings Methods (opens in a new tab)), and FeatureManagement.checkPermission “checks whether a custom permission is enabled” (FeatureManagement Class (opens in a new tab); both Apex Reference Guide, Winter ‘27, checked 2026-10-27).
And one switch per automation, so the bypass is scoped instead of “skip everything.” A custom metadata type, Automation_Switch__mdt, with one record per automation:
public with sharing class WorkOrderStatusOut { public static void publish(List<WorkOrder> orders, Map<Id, WorkOrder> oldOrders) { // One record per automation; switched off here, it's off everywhere it's deployed Automation_Switch__mdt sw = Automation_Switch__mdt.getInstance('WorkOrder_Status_Out'); if (sw != null && sw.Is_Off__c) { return; } // ... publish the status change for the partners }}getInstance(developerName) reads one custom metadata record by its name (Custom Metadata Type Methods (opens in a new tab), Apex Reference Guide, checked 2026-10-27).
In a flow, it’s the same idea: the first element is a decision.
The check comes first. Switched on, the flow steps aside.
The decision’s condition reads the same two switches, through flow’s global variables: $Permission is “the custom permission access of the user running the flow,” and $Setup reads hierarchy custom settings (Global Variables Resource (opens in a new tab), Salesforce Help, checked 2026-10-27). As a formula resource:
{!$Permission.Bypass_Automation} || {!$Setup.Automation_Bypass__c.Disable_Flows__c}In a validation rule, the bypass is one more condition. Here’s R12’s install rule, with the migration user allowed through (the field names are examples):
AND( NOT($Permission.Bypass_Automation), ISPICKVAL(Status, "Completed"), Install_Required__c, NOT(Install_Checklist_Complete__c))Validation rules reference a custom permission as $Permission.Custom_Permission_Name (How to Reference a Custom Permission in a Formula, Workflow Rule, or Validation Rule (opens in a new tab), Salesforce Help, checked 2026-10-27).
Salesforce’s decision guide calls custom permissions “the modern, scalable standard for implementing bypass logic,” and notes a bypass can be granted to one user, “or even temporarily with a specific expiration date/time” (Record-Triggered Automation (opens in a new tab), checked 2026-10-27). That’s the migration window, built into the grant.
These are examples to adapt, not a framework to paste in: build yours, test it in a sandbox, and test that the switch turns back off. And remember what you’ve built. A bypass is a permission to skip business rules. Grant it to the migration user for the migration window, record who has it, and take it away when the load is done (module 4 puts that in the runbook).
Test knowledge. Know the three places to keep a bypass and who each applies to: a custom permission (only the users whose permission sets grant it; checked with
$Permissionin flows and validation rules,FeatureManagement.checkPermissionin Apex), a hierarchy custom setting (the org, a profile or a user, the most specific value winning;$Setupin flows and formulas,getInstance()in Apex), and custom metadata (one switch per automation, deployable).
A Bypass Isn’t “Skip Everything”
Section titled “A Bypass Isn’t “Skip Everything””A bypass doesn’t mean the migration user ignores every rule in Salesforce. One automation should be bypassed, another must still run; a validation rule protecting a fundamental invariant still matters, a notification doesn’t; a downstream integration needs suppressing, a required relationship still needs checking. So I want bypasses that are intentional and scoped, not Migration_Mode__c = true, therefore nothing matters. The migration path still has rules, just the ones appropriate for migration.
And the bypass should represent an operational context, not an accident. A dedicated migration identity (module 2), a custom permission, configuration metadata, a feature flag, or a combination can recognize approved migration work. The identity can be part of the control, but I don’t want every automation hard-coded to User.Name = 'Migration User'. That’s brittle. Express the intent: if this is an approved migration operation, skip this side effect.
Validation Rules Need Judgment
Section titled “Validation Rules Need Judgment”“Close Date is required when an Opportunity is Closed Won” is a real data invariant; keep it for historical opportunities. A rule that forces a current-process field introduced three years ago is different: records from ten years ago never had it, and inventing a value makes the data worse. The question isn’t “do we turn off validation rules?” It’s which rules represent enduring data truth, and which represent today’s interactive process? That’s a data architect’s question.
Steve Trucking has one of each. Every Work Order must have a Retail Partner: that’s enduring truth, and it stays on for the load; a RouteDesk delivery without one goes to quarantine (module 1). But requirement R12 says an install can’t be closed without a completed checklist and specific photos, the water line, the drain line, the level. That’s today’s process, built for crews with the new mobile app. RouteDesk’s completed installs never had those photos. Bypass that rule for the migration identity, and load them as completed. Don’t invent photos.
The smell to watch for: the target requires a value, the source doesn’t have it, so “just put ‘Unknown’ in everything.” If Unknown is an approved value that truly describes the state, fine. If we’re inserting fake values to get past validation, we’re corrupting the data to satisfy the application. I’d rather design a migration exception, a nullable historical field, a transformation rule or a legacy-state value than pretend we know something we don’t.
Automation Multiplies the Number of Zeros
Section titled “Automation Multiplies the Number of Zeros”Load 2 million accounts; automation creates 2 tasks each: 4 million tasks. Intended, or an accident? Then each task fires another flow, the account automation updates a parent, publishes an event, recalculates something else. Migration performance isn’t how fast the Bulk API inserts accounts. The real workload is the transaction graph those inserts create. The Number of Zeros multiplies through automation.
Now zoom in on RouteDesk’s three red arrows and count.
Every record, times everything it sets off.
Chapter 9 turned on Change Data Capture for Work Orders, so Snowflake’s subscriber receives a change event for every create. That’s about 196,400 events in one weekend, and without an add-on the daily allocation for delivered events is 50,000 in Performance and Unlimited Editions, counted per subscriber (Change Data Capture Allocations (opens in a new tab), checked 2026-10-27). The partners would get status messages for about 190,000 deliveries they closed weeks ago. The finance ERP would count deliveries it has already invoiced, and the partners would be billed twice. And Recipients would get texts about deliveries that already happened.
Keep only the outcomes you need: one backfill, texts for the open deliveries, nothing to partners or finance.
External side effects are worse. Customer emails, billing requests, events consumed by production systems, ERP calls, support tickets, marketing updates: those systems don’t know it’s migration data, and once the message leaves Salesforce, undoing it may be impossible. Chapter 9 gave us the integration data contract; during migration planning, decide which of those arrows may operate, which are suppressed, and which are replaced by a synchronization after cutover. That decision belongs in the cutover plan.
Derived Data, Sharing, and the Staging Object
Section titled “Derived Data, Sharing, and the Staging Object”Rollups and other derived values: load a parent, then millions of children, and recalculate after every child? Maybe. Often it’s far cheaper to load everything and calculate once. The question is whether the derived result must be maintained record by record during the migration, or can be established after the dependent data is complete. That’s the same don’t need / simulate / defer decision.
Sharing is derived data too. Creating and transferring records triggers sharing rule calculation, and on a big load that can mean very long evaluations or timeouts. Salesforce lets an admin defer sharing calculations (sharing rules and group membership) and resume them afterward, but the feature isn’t on by default: Salesforce Support enables it. When you resume, you must run a full recalculation, and some sharing changes are still calculated immediately to protect data integrity (Defer Sharing Calculations (opens in a new tab)). Plan it, and plan the recalculation time.
Deferring has limits of its own. The catch-up usually runs as batch Apex, and that shares the org’s daily allowance of asynchronous Apex executions: “250,000 or the number of applicable user licenses in your org multiplied by 200, whichever is greater.” Only five batch jobs can be queued or active at once, with up to 100 more waiting in the flex queue (Execution Governors and Limits (opens in a new tab), Apex Developer Guide, Winter ‘27, checked 2026-10-27). Your catch-up competes with every other batch job in the org, so schedule it, and size it.
Test knowledge. Large loads trigger sharing recalculation. Salesforce Support can enable deferred sharing calculations (sharing rules and group membership), which you resume and recalculate after the load. Deferred work usually runs as batch Apex, within the daily asynchronous Apex limit and five concurrent batch jobs.
And sometimes the logic you need is simply too slow to load through. This is the special case module 1 mentioned. A process that takes a second or two per record is fine for users; for hundreds of thousands of records in a cutover window it means days, and trying to simulate an intricate object model in the load can mean a dozen tables. The technique I use: load into a staging object first, a light custom object with no automation that holds the import fields and lookups, then let a batch process work through it, calling the platform’s own logic to build the real records. The status on each staging row lets the batch work in chunks, pause and resume, and the original import fields stay alongside the records they created for tracing. You get the data in fast and catch up on the processing afterward.
Design for the Final State, and Write It Down
Section titled “Design for the Final State, and Write It Down”The goal isn’t “run production automation.” It’s arrive at the correct production state, and those aren’t the same. Normal processing for a new account derives a classification, creates an onboarding task, sends a notification and publishes to another system. For a migrated historical account, the right final state may be: classification yes, onboarding task no, welcome notification no, external publish maybe, depending on the synchronization plan. Blindly running normal automation reproduces a process that wasn’t designed for migration.
For a serious migration, write it down as an automation inventory:
| Automation | Normal behavior | Migration decision | Required migration outcome |
|---|---|---|---|
| Status out to partners | Send each status change to Redrock, Keystone, Brightwave | Don’t need it | None: the partners already have it |
| Change Data Capture to Snowflake | A change event per Work Order | Defer | One backfill of status history after the load |
| Delivery counts to finance | Count each completed delivery for invoicing | Don’t need it | None: already invoiced; reconcile the count instead |
| Day-before text | Text the Recipient with a tracking link | Run deliberately, open deliveries only | Monday’s Recipients get the link; none for delivered ones |
| Work Order status | Set by the crews’ app | Simulate | Status mapped in the preparation data store |
| Install checklist and photos (R12) | Block closing an install without them | Bypass for the migration identity | Completed installs load as completed; no invented photos |
| Every Work Order has a partner | Reject a Work Order without one | Keep | Missing partner: quarantined before the load |
Now the decision is visible: we can review it, test it, rehearse it and verify it after the load.
Rehearse the Bypass, Then Turn It Back On
Section titled “Rehearse the Bypass, Then Turn It Back On”Don’t make production the first time you use migration mode. The rehearsal should test the migration identity, the bypass controls, the automations that stay active, the simulated results, the deferred processes and the return to normal mode, then check: did anything fire that shouldn’t have, did anything fail to happen that should, does the final state match the architecture? That’s why the rehearsal needs the real automation configuration, or as close as practical.
Re-enabling is a cutover step: explicit, with a named owner, an expected time and verification. Not “remember to turn the flows back on.” The system isn’t ready for users until normal operation is restored and verified (module 4 puts it in the runbook).
And beware the catch-up storm. We suppressed downstream synchronization while loading RouteDesk’s records; now we switch the integration back on. Does it see five million “new” records and try to send them all? Maybe the downstream system already received them another way, maybe only changes after the cutover watermark should go, maybe it needs a controlled initial sync. The automation decision and the integration decision have to work together. Turning automation back on isn’t enough: know what it will do when it wakes up. For Steve Trucking, the status flows and the Change Data Capture subscriber should see only the changes made after cutover, never the weekend’s load.
AI Makes Bypass Design More Important
Section titled “AI Makes Bypass Design More Important”Now add agents that react to a new case, a changed account, a published event or a task in a queue. A migration creates data patterns at machine scale; do we want agents reacting to every migrated record? Probably not by accident. Agent-triggered processes belong in the same inventory as flows, triggers, notifications, integrations and events, and if the migration context should suppress them, design that deliberately.
Beyond the exam: what AI changes. Agents are another kind of side effect, one that may react autonomously to migrated data. Treat agent-triggered actions like any other automation: decide whether to run, simulate, defer or suppress them, and test the decision in rehearsal.
What an Architect Decides Here
Section titled “What an Architect Decides Here”- Which automations run, aren’t needed, are simulated or are deferred for each class of migrated data, knowing that turning one off means owning its business logic.
- Which validation rules represent enduring data truth, and which are current-process rules needing migration-specific treatment.
- How scoped bypasses are designed into every automation from the start, tested on and off, and deployed long before they’re needed, without an unrestricted “skip everything” path.
- How derived data, sharing recalculation and slow platform logic are handled: after the load, deferred, or through a staging object.
- Which external side effects and integrations are suppressed or deliberately caught up, and how rehearsal and cutover prove normal automation was safely restored.
Make It a Decision
Section titled “Make It a Decision”The migration isn’t successful because every flow ran, every trigger fired and every validation rule executed. That’s normal transaction behavior, and migration has a different job: move the data into the new architecture, preserve the truths that matter, create the derived values we need, avoid false side effects, keep the system controllable, then return it to normal. For each automation: don’t need it, simulate it, defer it, or deliberately let it run. But make it a decision. Don’t let five million records make it for you.
Explore
Section titled “Explore”- Salesforce Help, Defer Sharing Calculations (opens in a new tab) and Workflow Rules & Process Builder End of Support (opens in a new tab), checked 2026-11-01.
- Salesforce Help, Define Custom Settings (opens in a new tab), Global Variables Resource (opens in a new tab) (Flow) and How to Reference a Custom Permission in a Formula, Workflow Rule, or Validation Rule (opens in a new tab); Apex Reference Guide, FeatureManagement Class (opens in a new tab), Custom Settings Methods (opens in a new tab) and Custom Metadata Type Methods (opens in a new tab), Winter ‘27; all checked 2026-11-01.
- Salesforce Architects, decision guide, Record-Triggered Automation (opens in a new tab) (“Bypassing Automation”), checked 2026-11-01.
- Salesforce Architects, Well-Architected, Automation Patterns (opens in a new tab) and Resource and Cost Optimization (opens in a new tab), checked 2026-11-01.
- Salesforce, Apex Developer Guide, Execution Governors and Limits (opens in a new tab), Winter ‘27 (API version 68.0), and Change Data Capture Developer Guide, Change Data Capture Allocations (opens in a new tab), checked 2026-11-01.
- In this course: Integration and Data Movement (the integration data contract) and Designing for Scale.
