ESC

AI-powered search across all blog posts and tools

Flows · February 6, 2026

Scheduled Flow Patterns and Pitfalls

Scheduled Flows are powerful for time-based automation but full of subtle traps around time zones, batch sizing, and recursion. Here is what you need to know before you build.

☕ 9 min read 📅 February 6, 2026
  • Schedule-Triggered Flows and Scheduled Paths in Record-Triggered Flows solve fundamentally different problems and should not be confused
  • Scheduled Paths evaluate the wait condition at schedule time, not at the time the path was created — this causes common confusion around field value changes
  • Time zone handling in Scheduled Flows operates in UTC by default; always account for this when scheduling business-hours-relative automation

I have spent more time debugging Scheduled Flow problems than I care to admit. The feature is genuinely powerful, but it has enough subtle behavior differences from other flow types that it catches even experienced admins off guard. Let me walk you through the patterns that work and the pitfalls that have tripped up real orgs in production.

Two Different Features That Sound the Same

The first thing to get right is the distinction between two Flow features that both involve scheduling:

Schedule-Triggered Flows

Schedule-Triggered Flows run on a time schedule you define — daily, weekly, or at a specific time — and operate on a batch of records that match a SOQL filter you specify. Think of it as a cron job with a SOQL query built in.

Use when: You need to process a set of records on a recurring basis regardless of when each record was created.

Scheduled Paths

Scheduled Paths are part of Record-Triggered Flows. When a record meets a trigger condition, instead of processing immediately, the flow sets a scheduled wait. After the wait period expires, the scheduled path executes.

Use when: You need per-record time-delayed automation (e.g., “3 days after this case was created”).

Scheduling Behavior Comparison
Scheduling Behavior ComparisonSchedule-Triggered FlowMon 00:00Mon 09:00Tue 00:00Tue 09:00Wed 00:00Runs: queriesall matching recordsRuns againBatch: up to 2000Scheduled Path (Record-Triggered)Record triggersFlow entryWait: 3 days(evaluated per record)Scheduled path executes(re-evaluates entry conditions!)Another recordEach record has its own independent scheduled wait timer

They serve different purposes and have different governor limit profiles. Conflating them leads to choosing the wrong tool.

Schedule-Triggered Flows

When to Use Them

Use a Schedule-Triggered Flow when:

  • You need to process a set of records on a recurring basis regardless of when each record was created
  • The triggering condition is time-based (e.g., every morning, check all open cases where last activity was more than 7 days ago)
  • You do not need per-record timing — every record in the batch gets processed at the same scheduled time

Common use cases:

  • Daily SLA breach checks
  • Weekly data quality reports
  • Nightly sync operations
  • Monthly digest emails to account owners

Batch Size: The 2000 Record Limit

Schedule-Triggered Flows process records in batches of up to 2000 records per transaction. If your SOQL filter returns 5000 records, the flow runs across multiple batches automatically. Salesforce handles the batching — you do not need to implement it.

⚠️ Batch Implications
  • Avoid operations that aggregate across all records in a single transaction (counts, rollups) — each batch only has visibility into its own 2000 records
  • Actions that send emails count against per-transaction email limits (500 per transaction)
  • Platform Event publishes follow the standard 150 DML statements per transaction limit

The SOQL Filter Matters

The object and filter you define at the start of a Schedule-Triggered Flow is executed as a SOQL query. You should treat this like writing a performant SOQL query:

  • Filter on indexed fields where possible (Id, Name, ExternalId__c, CreatedDate, SystemModstamp)
  • Add a status filter to exclude already-processed records (so the batch does not grow unbounded)
  • Use date literals (LAST_N_DAYS:7) rather than computed date values where possible
🚨 Important

A Schedule-Triggered Flow that queries all Accounts with no filter will process every Account in your org every time it runs. Always include a status filter.

Scheduled Paths in Record-Triggered Flows

The Re-Evaluation Behavior

ℹ️ Critical Concept

When a record enters a Scheduled Path wait, Salesforce does not store a snapshot of the record at that moment. When the scheduled time arrives, Salesforce re-queries the record and re-evaluates the entry conditions for the path.

Practical implication: If your Scheduled Path entry condition is “Status equals New” and the record’s Status changes to “In Progress” before the wait expires, the Scheduled Path will not execute when the timer fires. The record no longer meets the entry condition.

This is sometimes the desired behavior (don’t send a follow-up if the case was already resolved), but it surprises people who expect the path to always execute.

If you need to guarantee execution regardless of field changes, use a Schedule-Triggered Flow with a filter that does not reference the status field.

Time Zones: The UTC Reality

Scheduled Paths evaluate their wait times in UTC. When you set a wait of “1 day from CreatedDate”, Salesforce adds 24 hours to the UTC timestamp of CreatedDate. This means:

  • A record created at 11 PM US Eastern (4 AM UTC next day) with a “1 day” wait executes 24 hours after 4 AM UTC — which is 4 AM UTC the following day, or 11 PM Eastern
  • This may or may not align with your business expectations
Business Hours Workarounds

For business-hours-aware automation, you have two options:

  1. Use a larger wait window (e.g., 2 days) and accept that execution time varies slightly
  2. Combine with a Flow scheduled path that waits until a specific time of day using a dynamic date formula
// Formula for "next 9 AM after 3 days"
DATEVALUE(CreatedDate) + 3 + (9/24) // Rough approximation

For precise business-hours scheduling, custom Apex with System.scheduleBatch gives you more control than Flow.

Bypass Patterns for Scheduled Paths

Scheduled Paths respect the same bypass mechanisms as other Record-Triggered Flow paths. You can add an entry condition at the scheduled path level that references a checkbox field like Automation_Paused__c = false. Setting this field on the record before the wait expires prevents the path from executing.

Practical Use Case Patterns

Pattern 1: Follow-Up Email Sequence

A classic use case: send a follow-up email 3 days after a lead is created if it has not been contacted.

Flow design:

  1. Entry condition: Lead is created
  2. Immediate path: Set a “Follow-Up Scheduled” timestamp field
  3. Scheduled path (3 days): Check Status != Contacted — if true, send email and increment follow-up counter
  4. Second scheduled path (7 days): Check Status != Contacted AND Follow_Up_Count__c >= 1 — if true, create a Task for the owner

The re-evaluation behavior works in your favor here: if the rep contacts the lead before day 3, the path does not fire.

Pattern 2: SLA Breach Warning

Flow design:

  1. Entry condition: Case is created with Priority = High
  2. Scheduled path (4 hours before SLA): Check Status != Closed — send Slack/email alert to case owner and manager
  3. Scheduled path (at SLA deadline): Check Status != Closed — escalate to supervisor, set Escalated flag

Note: For the “4 hours before SLA” timing, you would use a dynamic offset based on a custom SLA deadline date/time field populated by your business logic.

Pattern 3: Data Quality Monitoring with Schedule-Triggered Flow

Run daily at 8 AM to find Opportunities missing required fields 30 days before close:

Object: Opportunity
Filter: CloseDate = NEXT_N_DAYS:30
        AND StageName != 'Closed Won'
        AND StageName != 'Closed Lost'
        AND (Product_Line__c = null OR Competitor__c = null)

For each matching record, the flow:

  1. Creates a Task assigned to the opportunity owner
  2. Sends a Chatter post to the opportunity record
  3. Sets a Data_Quality_Alert__c checkbox (so the same record is not flagged again tomorrow — update your filter to exclude records with this set)

Common Pitfalls

Common Pitfalls and Fixes
Common Pitfalls and FixesPitfall: UTC Time Zone AssumptionScheduled actions fire in UTC.A “daily at 9 AM” schedule runs at9 AM UTC, not 9 AM your local time.Fix: Convert to UTC offset in schedule.Pitfall: No “Already Processed” GuardA Schedule-Triggered Flow with no statusfilter processes the same records every day.Leads to duplicate emails, duplicate tasks.Fix: Filter on or update a “processed” field.Pitfall: Re-evaluation SurpriseScheduled Path re-evaluates entry conditions.If the record changes before the wait ends,the path may silently not execute.Fix: Log scheduled path activations to a field.Pitfall: Email Limits at Scale500 emails per batch transaction.A 2000-record batch sending one emaileach will span 4 sub-transactions.Fix: Stagger sends or use marketing tools.

Bulkification in Schedule-Triggered Flows

Schedule-Triggered Flows are inherently bulkified — the 2000-record batch is processed together. However, operations within the flow still need to follow bulkification principles:

  • Get Records elements: Each Get Records element is one SOQL query regardless of batch size. Use these efficiently.
  • Update Records elements: Accumulate records and update in a single Update Records element at the end, not one per record.
  • Apex actions called from Flow: Your Apex invocable methods must accept List<> parameters and process them in bulk. A Flow invocable method called inside a loop is called once per record — this is a governor limit disaster.

The Problem

You built a Scheduled Path on a Case record-triggered Flow: “If Status = New after 48 hours, escalate to manager.” Users are complaining that cases are being escalated even after they have been resolved. The Flow appears to ignore the re-evaluation check.

The Solution

The re-evaluation is working correctly — the issue is your entry condition. The Scheduled Path re-evaluates whether the record still meets the entry conditions when the timer fires. Check that your path entry condition explicitly filters for Status = New at the scheduled path level, not just at the Flow trigger entry. If the condition is only on the Flow trigger (not on the Scheduled Path itself), the path will execute for all records that originally triggered the Flow, regardless of their current status.

💡 Pro Tip

Always add a “processed” guard field (a checkbox like Daily_Alert_Sent__c) to your Schedule-Triggered Flow filter. Without it, every execution of the Flow re-processes the same matching records. Update the field at the end of the Flow and include Daily_Alert_Sent__c = false in your SOQL filter. Reset it with a separate nightly Flow if the record should be eligible again after 24 hours.

Monitoring Scheduled Flows

Salesforce provides the Time-Based Workflow or Paused and Waiting Interviews list to see pending scheduled flow executions. Navigate to Setup > Flows > Paused and Waiting Flow Interviews.

Querying Flow Errors Programmatically

You can also query scheduled interviews directly:

// NOTE: FlowExecutionErrorEvent is a Platform Event, not a standard
// queryable object. You cannot use SOQL to query it. Instead, consume
// it via an Apex trigger on the event, a CometD/Streaming subscription,
// or a Platform Event-Triggered Flow.
//
// Example: Apex trigger to capture flow errors
trigger FlowErrorHandler on FlowExecutionErrorEvent (after insert) {
    for (FlowExecutionErrorEvent evt : Trigger.New) {
        System.debug('Flow error: ' + evt.FlowApiName + ' — ' + evt.Message);
    }
}

For production monitoring, setting up a Flow Error Email (Setup > Process Automation Settings > Apex Exception Email) ensures you are notified when scheduled flows fail.

What is the most complex scheduling automation you have built in Flow, and did you run into any of these pitfalls along the way?


Knowledge Check

A Scheduled Path has an entry condition of 'Status = New' and a 48-hour wait. The record's Status changes to 'In Progress' after 24 hours. What happens when the timer fires?
What is the maximum batch size for a Schedule-Triggered Flow?

How did this article make you feel?

Comments

Salesforce Tip

🎉

You finished this article!

What to read next

Contents