10.1 Logic Controls: Conditions, Switches, Apply to Each & Do Until Loops
Key Takeaways
- Condition actions provide binary branching ('If yes' / 'If no') supporting nested AND/OR logic groups and relational comparisons.
- Switch actions provide multi-branch execution matching a single string or integer expression against up to 25 case branches plus an optional default case.
- Apply to each iterates over JSON arrays, defaulting to parallel execution (up to 50 threads); setting Concurrency Control to 1 (Sequential) is mandatory when modifying variables to prevent race conditions.
- Do Until loops execute actions iteratively until a condition evaluates to true, evaluating criteria at the end of each iteration (guaranteeing at least one run).
- Do Until loops are governed by hard termination limits: Count limit (default 60, maximum 5,000) and Timeout limit in ISO 8601 format (default PT1H, maximum P30D), terminating whenever either threshold is reached.
Logic Controls: Conditions, Switches, Apply to Each & Do Until Loops
Process automation in enterprise environments rarely follows a strictly linear path. Real-world workflows demand sophisticated decision trees, parallel data processing, multi-path routing, and iterative polling against asynchronous backends. Within Microsoft Power Automate, Logic Controls are the architectural building blocks that govern execution flow. Built atop the Azure Logic Apps workflow engine, these control actions enable functional consultants to evaluate runtime expressions, route execution dynamically, iterate through collections, and repeat actions until specific business criteria are satisfied.
For the PL-200: Microsoft Power Platform Functional Consultant certification exam, you must master the operational mechanics, configuration limits, thread-safety considerations, and performance trade-offs across four core control structures: Condition, Switch, Apply to each, and Do Until.
1. Flow Control Architecture & Execution Mechanics
Every cloud flow action executes within a directed execution graph. Control actions act as container nodes that encapsulate child actions, dynamically evaluating conditions to determine whether child branches execute, how many times they repeat, and whether iterations run concurrently or sequentially.
+-----------------------------------------------------------------------------+
| POWER AUTOMATE LOGIC CONTROL TAXONOMY |
| |
| +---------------------------------------------------------------------+ |
| | POWER AUTOMATE ENGINE RUNTIME | |
| +---------------------------------------------------------------------+ |
| | | | |
| v v v |
| +-----------------------+ +-----------------------+ +-----------+ |
| | BRANCHING CONTROLS | | LOOPING CONTROLS | | CONTAINERS| |
| | - Condition (If/Else) | | - Apply to each | | - Scope | |
| | - Switch (Multi-Case) | | - Do Until | | - (Try/ | |
| +-----------------------+ +-----------------------+ | Catch) | |
| +-----------+ |
+-----------------------------------------------------------------------------+
2. Condition Action: Binary Decision Branching
The Condition action evaluates one or more relational criteria to boolean true or false, splitting the flow into two mutually exclusive execution paths:
If yes(True branch): Executes when the compound logical condition evaluates totrue.If no(False branch): Executes when the compound logical condition evaluates tofalse.
+-----------------------------------------------------------------------------+
| CONDITION ACTION ARCHITECTURE |
| |
| +---------------------------------------------+ |
| | CONDITION (Logical Evaluator) | |
| | [Attribute / Value] [Operator] [Criteria] | |
| +---------------------------------------------+ |
| | |
| +---------------+---------------+ |
| | | |
| [Evaluates TRUE] [Evaluates FALSE] |
| v v |
| +-----------------+ +-----------------+ |
| | IF YES | | IF NO | |
| | (Branch Actions)| | (Branch Actions)| |
| +-----------------+ +-----------------+ |
+-----------------------------------------------------------------------------+
Relational Operators and Comparison Mechanics
Each row in a Condition compares a left operand (dynamic token or expression) against a right operand using a selected operator:
| Operator | Description | Data Type Compatibility |
|---|---|---|
is equal to / is not equal to | Exact value equality or inequality | String, Number, Boolean, Null |
is greater than / is greater than or equal to | Numeric or chronological comparison | Integer, Float, ISO 8601 Date |
is less than / is less than or equal to | Numeric or chronological comparison | Integer, Float, ISO 8601 Date |
contains / does not contain | Substring presence or item in collection | String, Array |
starts with / does not start with | Prefix evaluation | String |
ends with / does not end with | Suffix evaluation | String |
Compound Logic Groups (AND / OR)
Makers can combine multiple comparison rows into complex relational statements:
AndGroup: All rows within the group must evaluate totruefor the group to betrue.OrGroup: If any row within the group evaluates totrue, the group evaluates totrue.- Nested Logic Groups: Sub-groups can be nested up to multiple levels deep (e.g.,
(Status eq 'Active' AND Revenue > 100000) OR (Tier eq 'VIP')).
[!CAUTION] Data Type Coercion in Conditions: Power Automate enforces strict typing in expressions but attempts automatic coercion in the Condition designer. However, comparing an integer column
statuscode(e.g.,864500001) against a string literal'864500001'will evaluate tofalse. Always ensure operands match in underlying data type, or use explicit conversion functions likeint()orstring().
3. Switch Action: Multi-Path Routing
When a business requirement dictates evaluating a single variable or dynamic token against multiple discrete possible values (such as an approval status, order category, or state code), chaining multiple nested Condition actions becomes unreadable, error-prone, and inefficient. The Switch action provides clean, performant multi-way branching.
+-----------------------------------------------------------------------------+
| SWITCH ACTION ARCHITECTURE |
| |
| +---------------------------------------------------+ |
| | SWITCH: On expression / token | |
| | (e.g., triggerOutputs()?['priority']) | |
| +---------------------------------------------------+ |
| | | | | |
| [Value = 'High'] [Value = 'Med'] [Value = 'Low'] [No Match] |
| v v v v |
| +-------------+ +-------------+ +-------------+ +-------------+|
| | CASE 1 | | CASE 2 | | CASE 3 | | DEFAULT ||
| | (Escalate) | | (Standard) | | (Batch Q) | | (Log Unk.) ||
| +-------------+ +-------------+ +-------------+ +-------------+|
+-----------------------------------------------------------------------------+
Switch Configuration Rules & Limits
- Target Expression: The Switch evaluates a single input expression or dynamic content token (typically of type
StringorInteger). - Case Branches: You can configure up to 25 discrete Case branches per Switch action. Each Case specifies an exact matching value.
- Matching Logic: The Switch performs strict equality matching (
equals). It does not support inequality operators (>,<,contains) inside case headers. - Default Case: If the evaluated expression does not match any configured Case, execution routes into the Default branch. While configuring actions inside the Default branch is optional, it is best practice for defensive logging and unhandled scenario alerts.
- Execution Exclusivity: Unlike programming languages that require a
breakstatement to prevent fallthrough, Power Automate Switch cases are mutually exclusive; exactly one branch executes per evaluation.
4. Apply to Each Action: Array Iteration & Concurrency Control
The Apply to each action is a loop container designed to iterate through an incoming collection or array (such as records returned from Dataverse List rows, attachments from an email, or items from a SharePoint list).
+-----------------------------------------------------------------------------+
| APPLY TO EACH: CONCURRENCY MODES |
| |
| [DEFAULT: CONCURRENT (PARALLEL)] [SEQUENTIAL (DEGREE = 1)] |
| - Up to 50 concurrent threads - Exactly 1 iteration at a time |
| - Non-deterministic execution order - Strict chronological order |
| - Fast throughput for independent tasks - MANDATORY when updating |
| - DANGER: Variable race conditions! variables inside loop |
| |
| Thread 1: Item[0] -> API Call Iter 1: Item[0] -> Var = 1 |
| Thread 2: Item[1] -> API Call Iter 2: Item[1] -> Var = 2 |
| Thread 3: Item[2] -> API Call Iter 3: Item[2] -> Var = 3 |
+-----------------------------------------------------------------------------+
Dynamic Content Inside the Loop: item()
Within the loop body, child actions reference the current array element using the dynamic content token Current item (resolved in WDL as the item() function). If looping over an array of JSON objects, properties are accessed via item()?['FieldName'].
Concurrency Control & Thread Safety
By default, modern Power Automate flows execute Apply to each loops in parallel to maximize throughput.
- Degree of Parallelism: In the action's Settings pane, makers can enable Concurrency Control and configure the Degree of Parallelism from
1to50. - The Variable Race Condition Trap: Variables in Power Automate are global to the entire flow execution run. If an
Apply to eachloop updates a variable (e.g.,Increment variable,Set variable, orAppend to array variable) while Concurrency Control is set to parallel, multiple concurrent threads will read and write to the same memory space simultaneously. This produces race conditions, dropped increments, and corrupt data.
[!IMPORTANT] PL-200 Golden Rule for Loops & Variables: Whenever a variable is modified inside an
Apply to eachloop, you MUST enable Concurrency Control on the loop and set the Degree of Parallelism to1(Sequential execution). If sequential processing causes performance bottlenecks, replace the loop-and-variable pattern with declarative Data Operations (Select,Filter array,Join).
5. Do Until Action: Conditional Repetition & Termination Limits
The Do Until action repeats a block of actions until a specified relational expression evaluates to true. It is standardly used for asynchronous polling patterns, such as waiting for a long-running external job to finish, polling a Dataverse row until an approval status changes, or retrying a transient service call with a Delay.
+-----------------------------------------------------------------------------+
| DO UNTIL LOOP EXECUTION |
| |
| +----------------------------------+ |
| | ENTER DO UNTIL | |
| +----------------------------------+ |
| | |
| v |
| +----------------------------------+ |
| | EXECUTE LOOP ACTIONS | |
| | (e.g., Get row, Delay 60s) | |
| +----------------------------------+ |
| | |
| v |
| +----------------------------------+ |
| | EVALUATE EXIT CONDITION | |
| | (e.g., Status eq 'Completed') | |
| +----------------------------------+ |
| | |
| +----------------+----------------+ |
| | | |
| [Condition FALSE] [Condition TRUE] |
| [AND Limits NOT reached] [OR Limit REACHED] |
| | | |
| +-------- (Repeat Loop) v |
| +----------------+ |
| | EXIT LOOP | |
| +----------------+ |
+-----------------------------------------------------------------------------+
Do-While Evaluation Semantics
Unlike traditional while loops in programming languages (which check the condition before executing the first iteration), Power Automate evaluates the Do Until exit condition at the end of each iteration. This guarantees that the actions inside the Do Until block will always execute at least once, regardless of the initial condition state.
Built-in Loop Limits (Guardrails)
To prevent infinite loops that consume infinite API calls and lock execution threads, Power Automate enforces strict runtime limits on every Do Until action. The loop terminates whenever either the exit condition evaluates to true OR either limit threshold is reached:
| Limit Property | Default Value | Maximum Allowed Value | Format / Description |
|---|---|---|---|
| Count Limit | 60 iterations | 5,000 iterations | Positive integer representing maximum loop cycles. |
| Timeout Limit | PT1H (1 Hour) | P30D (30 Days) | ISO 8601 Duration format (PT1H = 1 hr, PT15M = 15 min, P1D = 1 day). |
// ISO 8601 Duration Syntax Cheat Sheet for PL-200:
PT15M --> Period Time: 15 Minutes
PT1H --> Period Time: 1 Hour
PT2H30M--> Period Time: 2 Hours and 30 Minutes
P1D --> Period: 1 Day
P7D --> Period: 7 Days
P30D --> Period: 30 Days (Platform Maximum)
[!WARNING] Silent Exit on Limit Expiration: When a
Do Untilloop reaches its Count or Timeout limit without the exit condition becoming true, the action does NOT fail with an error; it completes with statusSucceededand continues to the next action! If downstream actions depend on the condition having actually been satisfied, you must place aConditionimmediately after the loop to verify the final state.
6. Logic Control Architectural Comparison
| Architectural Dimension | Condition | Switch | Apply to each | Do Until |
|---|---|---|---|---|
| Primary Purpose | Binary true/false branching with complex AND/OR logic | Multi-path routing for a single expression against discrete values | Iterating over items in an array collection | Repeating actions until an external condition becomes true |
| Branch / Iteration Limit | 2 branches (If yes / If no) | Up to 25 Cases + 1 Default | Unbounded (bound by source array size & pagination) | Max 5,000 iterations or 30 days (default 60 / PT1H) |
| Evaluation Timing | Once upon entering step | Once upon entering step | Evaluates per item | Evaluates at end of each loop iteration |
| Concurrency Support | N/A (single execution) | N/A (single execution) | Configurable parallel (1 to 50 threads) | Sequential by nature |
| Variable Safety | Safe | Safe | Unsafe if parallel; requires Degree of Parallelism = 1 | Safe (sequential execution) |
A functional consultant is building a cloud flow that queries an array of 500 purchase orders from Dataverse using 'List rows'. Inside an 'Apply to each' loop, the flow evaluates each purchase order, increments an integer variable 'varTotalHighValueOrders' whenever the order amount exceeds $50,000, and updates the purchase order status. During testing, running the flow against 500 records results in an inaccurate, non-deterministic total count in 'varTotalHighValueOrders'. What is the root cause of this discrepancy and how should it be resolved?
An enterprise flow must monitor an external payment processing gateway. After dispatching an asynchronous charge request, the flow must poll the payment status endpoint every 2 minutes until the status returns 'Settled'. If the transaction is not settled within 4 hours, the flow must stop polling and escalate to a finance manager. The consultant configures a 'Do Until' loop containing a 'Get payment status' action and a 'Delay' of 2 minutes. How should the consultant configure the Do Until loop limits to enforce this business rule?
A functional consultant needs to route customer support tickets originating from an instant flow to five different regional support queues based on the ticket's 'Region' choice column ('North', 'South', 'East', 'West', 'Central'). If a ticket has an unassigned or unrecognized region, it must be assigned to the 'Global Tier 1' queue. What is the most efficient and maintainable control structure to implement this routing logic?
A consultant configures a 'Do Until' action where the exit condition is set to 'Status is equal to Complete'. Before the loop starts, the variable 'Status' is already set to 'Complete'. Which statement correctly describes the execution behavior of the Do Until action?