SfSkills Domains Docs GitHub

Home / flow / flow-migration-from-trigger

flow-migration-from-trigger

Decide whether an existing Apex trigger should be rewritten as a Flow, and execute the migration safely. Covers the decision criteria (complexity, ownership, performance), side-by-side rollout, test-coverage. NOT for migrating Process Builder / Workflow Rule to Flow (use those migration skills) — use flow/process-builder-to-flow-migration.

Open the skill folder on GitHub


Flow Migration from Trigger

Core concept — not every trigger should migrate

Apex triggers earn their complexity. Migration is justified when Flow can credibly carry the load AND admin ownership is desirable. Migration is harmful when:

Migration decision matrix

Trigger characteristicMigrate to Flow?
Single-object field derivation✅ Yes — use Before-Save record-triggered flow
Create related records on save✅ Yes — After-Save record-triggered flow
Cross-object updates with moderate logic✅ Yes — After-Save record-triggered flow
Bulk processing (1000+ records per transaction)⚠️ Maybe — benchmark before migrating
Callouts or async work⚠️ Route via Scheduled Path or Platform Event
SavePoint / complex transaction control❌ No — keep Apex
Recursion control via static context❌ No — keep Apex
Integration with @future / Queueable❌ No — keep Apex
Custom exception wrapping / logging frameworks❌ No — keep Apex
SOQL-heavy joins and aggregations❌ No — keep Apex
  1. Read the trigger + handler end-to-end. Note all DML, SOQL, and decision branches.
  2. Classify each branch against the decision matrix. If any branch is "No", consider keeping Apex OR splitting the trigger (keep complex branches in Apex, migrate simple branches to Flow).
  3. Inventory tests. Every test case that exercises the trigger must still pass after migration. If coverage is weak, shore it up BEFORE migration, not after.
  4. Design the Flow. Match the trigger's timing (Before-Save vs After-Save), bulk context, and field updates.
  5. Plan side-by-side rollout. Deploy the Flow inactive; activate in sandbox; run existing tests; smoke-test against a business-representative data set; activate in prod behind a Custom Permission for a subset of users.
  6. Deactivate the trigger. Don't delete until 2+ release cycles confirm the Flow is stable. Keep the trigger source code for rollback.
  7. Declare migration complete only when: tests green, zero runtime errors for 30 days, admin team confirms ownership.

Key patterns

Pattern 1 — Simple field-derivation migration

Original trigger handler:

for (Account acc : Trigger.new) {
    if (acc.Billing_Country__c == 'United States') {
        acc.Region__c = 'NA';
    } else if (acc.Billing_Country__c == 'Germany') {
        acc.Region__c = 'EMEA';
    }
}

Flow equivalent (Before-Save record-triggered):

[Decision: Billing_Country__c]
  ├── "United States" → [Assignment: $Record.Region__c = 'NA']
  ├── "Germany"       → [Assignment: $Record.Region__c = 'EMEA']
  └── default         → [Assignment: $Record.Region__c = 'ROW']

Benefits post-migration:

Pattern 2 — Partial migration

Handler with two responsibilities:

Split:

The test suite must verify both fire in the correct order (Before-Save Flow fires first, then Apex After-Insert/Update trigger).

Pattern 3 — Side-by-side rollout with Custom Permission

Trigger handler:
  if (!FeatureManagement.checkPermission('New_Flow_Active')) {
      // run the old logic
  } else {
      // skip; flow will handle
  }

Admins grant New_Flow_Active Custom Permission to a PSG; ramps from 1 user → 10% → 100%. If regression, revoke PSG; old logic resumes.

Pattern 4 — Bulk benchmark before migration

Bulk-heavy trigger (1000+ records per batch): before migrating, measure per-record time in Apex vs expected Flow runtime. Flows process per record with element overhead; complex Flow logic at scale can exceed Apex by 2-5× in CPU time.

Measurement:

Bulk safety

Error handling

Well-Architected mapping

Gotchas

See references/gotchas.md.

Testing

The migration test strategy is parity testing:

  1. Run the existing trigger test suite against the pre-migration org state; record outcomes.
  2. Deactivate trigger, activate Flow.
  3. Re-run the same test suite; every test must produce identical outcomes.
  4. If any test fails, the migration introduced a regression — don't proceed.

Add NEW test cases that specifically exercise Flow-only concerns (fault paths, Before-Save semantics).

Official Sources Used

Package files