Excelgoodies logo +31 97 010285556

LEARN THIS HANDS ON

Power Apps & Power Automate

. Live Online FILLING FAST
View all upcoming batches
Trigger-Based vs Scheduled Flows in Power Automate: Event-Driven Without Punishing Your APIs

Trigger-Based vs Scheduled Flows in Power Automate: Event-Driven Without Punishing Your APIs

You deploy a new flow against a line-of-business API, and within a day the API owner complains about traffic spikes and throttling. The logic is fine; the problem is how and when the flow runs. This article walks through designing trigger-based vs scheduled flows in Power Automate so your event-driven processes stay responsive without hammering your APIs.

The Scenario: SharePoint Orders, a CRM API, and Angry Owners

A typical setup:

  • Orders are stored in a SharePoint list.
  • A custom connector calls a CRM API to create or update customer records.
  • A Power Automate flow keeps SharePoint and CRM in sync.

The first implementation often looks like this:

  • Scheduled cloud flow running every 5 minutes.
  • Uses Get items on the SharePoint list with a filter for Modified in the last 5 minutes.
  • Loops through results and calls the CRM API once per item.

Symptoms:

  • CRM API hits its rate limits during busy periods.
  • Flow runs even when no items changed, still making API calls (e.g., status checks).
  • Hard to reason about which changes were processed when.

We’ll rework this into an event-driven design using trigger-based flows and a small amount of buffering, then compare when scheduled flows are still the right choice.

Trigger vs Scheduled Flows: What Actually Happens Under the Hood

In Power Automate (cloud flows):

  • Trigger-based flows start when an event or condition is met.

    • Examples: When an item is created (SharePoint), When an item is created or modified (SharePoint), When a row is added (Dataverse), When an HTTP request is received, When a message is added to a queue.
    • Many triggers are push-based (service notifies Power Automate), some are poll-based (Power Automate checks periodically).
  • Scheduled flows start on a fixed recurrence.

    • Trigger: Recurrence (built-in).
    • You control frequency, interval, and time zone.

Key behavioural points that matter for API load:

  • Recurrence triggers will fire on schedule regardless of data changes.
  • Polling triggers will call the underlying service on each polling interval.
  • Push triggers rely on the service’s event model; they don’t poll continuously.
  • Each flow run is an independent execution with its own action count and connector calls.

From an API owner’s perspective, your design choices boil down to:

  • How many flow runs you generate.
  • How many connector/API calls each run makes.
  • How you handle bursts of events.

Why the First Design Hammers the CRM API

Let’s look at the scheduled design in more detail.

Flow 1: Scheduled sync

  • Trigger: Recurrence every 5 minutes.
  • Action: Get items from SharePoint where Modified >= utcNow() - 5 minutes.
  • For each item: call CRM API via custom connector.

Problems:

  1. Runs with no changes

    • Get items still executes against SharePoint every 5 minutes.
    • If you do any external checks (e.g., CRM status), those calls fire even with no new data.
  2. Overlapping windows and duplicates

    • If a run is delayed or slow, the “last 5 minutes” window overlaps with the previous run.
    • Items can be processed twice, doubling API calls.
  3. Bursts map directly to API spikes

    • If 500 items are modified in 5 minutes, that run will attempt 500 CRM calls.
    • The flow doesn’t naturally smooth or batch those calls.
  4. No native backpressure

    • The flow doesn’t know about CRM rate limits.
    • Unless you explicitly handle responses and throttle, it just keeps calling.

The scheduled model is simple to reason about time-wise, but blind to event volume and API constraints.

Moving to Event-Driven: Trigger-Based Flow for Order Changes

For SharePoint, the natural move is a trigger-based flow:

Flow 2: Order change event flow

  • Trigger: When an item is created or modified (SharePoint).
  • Actions:
    • Evaluate the change.
    • Call CRM API only when relevant.

This immediately changes the shape of load:

  • No runs when nothing changes.
  • One run per changed item (depending on trigger behaviour and batching—more on that below).
  • You can apply per-item logic before calling external APIs.

A common pattern is to buffer events instead of calling CRM directly from the trigger flow. For example:

  • Flow A (trigger-based) writes changes into a queue (Azure Queue, Service Bus, or a Dataverse table).
  • Flow B (worker) processes messages from that queue with controlled concurrency.

This gives you:

  • Event-driven ingestion from SharePoint.
  • Controlled, rate-limited processing against the CRM API.

Example: Writing Order Changes to a Queue Table

Assume you use Dataverse as a simple queue table OrderSyncQueue with columns:

  • OrderId (text)
  • OperationType (choice: Create, Update)
  • QueuedAt (datetime)

Flow A: SharePoint trigger to queue

  • Trigger: When an item is created or modified (SharePoint).
  • Actions:
    • Map the SharePoint item to OrderId and OperationType.
    • Add a new row in OrderSyncQueue.

You now have one short flow per change, with no CRM calls yet.

Scheduled Worker Flows: When Scheduling Is the Right Tool

Trigger-based flows are ideal for capturing events. Scheduled flows are still useful as workers for controlled processing.

Flow B: Scheduled queue processor

  • Trigger: Recurrence every few minutes.
  • Actions:
    • Get a bounded set of rows from OrderSyncQueue.
    • Call CRM for each row, with concurrency tuned.
    • Mark rows as processed or delete them.

This hybrid design avoids hammering the API because:

  • You control batch size per run.
  • You control run frequency.
  • You control parallelism via the flow’s concurrency settings.

Controlling Concurrency on the Worker Flow

For flows that call external APIs heavily:

  • Open Settings for the Apply to each loop.
  • Enable Concurrency Control.
  • Set Degree of Parallelism to a number that respects the API’s limits.

If the CRM API can safely handle, say, 5 concurrent calls from this process:

  • Set parallelism to 5.
  • Limit each run to a fixed batch size (e.g., 100 queue rows).

This gives predictable load:

  • Max concurrent calls from this flow: 5.
  • Max calls per run: 100.
  • Total throughput: batch size × runs per hour, which you control by recurrence.

You’ve now used a scheduled flow in a way that protects the API, rather than hammering it.

Designing Trigger-Based Flows That Don’t Over-Fire

Trigger-based flows can also generate too many runs if you’re not careful. The main levers:

  1. Trigger choice

    • Prefer triggers that are push-based where available.
    • For SharePoint lists, When an item is created / When an item is created or modified is event-driven.
    • For Dataverse, When a row is added, modified or deleted is event-driven.
  2. Trigger conditions

    • Use trigger conditions to filter which events actually start the flow.
    • This reduces flow runs and downstream API calls.

Example trigger condition for SharePoint: only run when Status = ReadyForSync.

@equals(triggerBody()?['Status'], 'ReadyForSync')

You configure this in the trigger’s Settings → Trigger Conditions.

  1. Avoid unnecessary retriggers
    • If your flow updates the same item that triggers it, make sure you don’t cause an endless loop.
    • Use a flag column or more specific trigger conditions to avoid self-triggering updates.

By reducing how often your trigger fires, you reduce how often you even have the opportunity to call external APIs.

Handling API Limits and Throttling Explicitly

Even with good trigger/schedule design, you need to handle API constraints:

1. Retry Policies

Most connector actions support configurable retry policies.

  • Default behaviour generally retries on transient failures.
  • You can adjust:
    • Retry count.
    • Interval.

For APIs with strict rate limits, consider:

  • Lower retry count to avoid extended hammering.
  • Add explicit delay when you detect throttling (e.g., HTTP 429) via condition + Delay action.

2. Response-Based Throttling

Pattern:

  • Call CRM API.
  • If response indicates rate limit reached (e.g., 429 or specific error code):
    • Delay for a short period.
    • Optionally move the item back to the queue for later processing.

This works best in the worker flow, not the trigger flow, because you already control batch size and concurrency there.

3. Action Count Awareness

Power Automate has limits on actions per 24 hours per user/environment depending on licence and capacity.

  • High-frequency scheduled flows with many actions can hit these limits even before the external API complains.
  • Event-driven designs usually reduce unnecessary actions because they only run when something actually changes.

Comparing Designs on the Order Sync Scenario

Let’s compare the three designs:

A. Pure Scheduled Sync

  • Recurrence every 5 minutes.
  • Get items + loop + CRM call per item.

Impact:

  • Runs regardless of changes.
  • Bursts map directly to CRM call bursts.
  • Overlapping windows can double-process items.

B. Direct Trigger-Based CRM Calls

  • Trigger: When an item is created or modified (SharePoint).
  • Each run calls CRM immediately.

Impact:

  • No runs without changes.
  • Potentially many concurrent runs if many items change at once.
  • CRM sees one call per item change, possibly too bursty.
  • Flow A: Trigger-based, writes changes to queue.
  • Flow B: Scheduled, processes queue in controlled batches with limited concurrency.

Impact:

  • Event-driven ingestion from SharePoint.
  • CRM call volume is capped per batch and per minute.
  • Easier to reason about throughput and to adjust without touching the ingestion flow.

Design C is usually the sweet spot for “event-driven but API-friendly” in real environments.

When a Pure Scheduled Flow Still Makes Sense

Not everything should be event-driven. Scheduled flows are still the right choice when:

  • The source system has no reliable event model or connector trigger.
  • You’re doing aggregation or housekeeping that doesn’t map to single events.
  • The external API has strict daily windows (e.g., only call between specific times).

Even then, you can:

  • Keep recurrence low (e.g., hourly instead of every few minutes).
  • Use filters to limit the data processed per run.
  • Apply concurrency control and batch limits against external APIs.

Practical Takeaway: Separate Ingestion from Processing

The most effective way to design trigger-based vs scheduled flows in Power Automate without hammering your APIs is to separate event ingestion from API processing:

  • Use trigger-based flows to capture changes as they happen and write them to a queue or staging table.
  • Use scheduled worker flows to process that queue with explicit limits on batch size, frequency and concurrency.

If your current flows call external APIs directly from high-frequency schedules, start by introducing a queue and a worker flow. That single structural change usually turns an unpredictable API spike into a controllable, measurable workload.

Editor's Note

This article reflects a shift from monolithic, high-frequency scheduled flows to event-driven designs with queued workers, which matters most for teams integrating Power Automate with rate-limited line-of-business APIs and shared data platforms.

Professionals who want to apply these patterns to their own data can explore Excelgoodies' Power Automate Course programme - taught live by instructors, with certification awarded once a real project is running at work.

Insights compiled through ongoing industry research and discussions within the Excelgoodies Analytics Community.

Power Automate

New

Next Batches Now Live

Power BIPower BI
SQLSQL
Power AppsPower Apps
Power AutomatePower Automate
Microsoft FabricMicrosoft Fabrics
AzureAzure Data Engineering
Explore Dates & Reserve Your Spot → Reserve Your Spot →