Variables in Power Automate: Necessary Tool or Bad Design?
A recent LinkedIn post of mine sparked an unexpectedly large discussion about variables in Power Automate. What started as a simple idea around batch variable creation quickly turned into a debate about whether variables should be used at all.
Some experienced builders argued that any flow using multiple variables deserves scrutiny. Others went further, suggesting that most variables can be replaced entirely through expressions, Compose actions, or better architecture.
The conversation raised an interesting question:
Are variables really a sign of poor flow design, or are they a tool that gets overused sometimes?
After reading all of the comments and reflecting on some of my own automations, I think the answer sits somewhere in the middle.
My position is simple:
Avoiding variables is not automatically an optimization.
AND
Using variables everywhere is not automatically good design.
Like most things in Power Automate, the right answer depends on what problem you’re trying to solve.

Why This Discussion Started
The original post came from a semi-annual performance review automation I built.
Twice per year, the flow gathers information from multiple SharePoint lists, calculates metrics, compares results to previous review periods, summarizes survey feedback, analyzes training data, and generates personalized review emails for each employee.
The flow included separate processing scopes for our 3 team members (including myself).
Within each scope, the flow needed to track:
- Submission counts
- Reporting periods
- Training metrics
- Topic hours
- Session-type totals
- Debrief statistics
- Survey scores
- Feedback comments
- Email display content
- Comparison metrics
At one point I found myself creating what felt like dozens of variables.

The “reimagined” Initialize Variable action discussed in the post
The original challenge that sparked the post wasn’t actually about whether variables were necessary. It was:
Why is creating and organizing large groups of related variables such a painful experience in Power Automate?
The Argument Against Variables
Several experienced Power Automate builders pointed out something that’s absolutely true:
Many makers use variables when they don’t need them.
A common beginner pattern looks like this:
- Get a value.
- Store it in a variable.
- Reference the variable later.
In many cases, that middle step isn’t needed.
Because Power Automate actions expose their outputs globally throughout the flow, you can often reference an action’s output directly.
For example, if you calculate a total once and never change it again, a Compose action is often a better choice than a variable.
Instead of creating:
Initialize Variable
Set Variable
Use VariableYou can simply:
Compose
Use Compose OutputLess complexity, fewer actions, easier maintenance. There’s real value in challenging unnecessary variables.
Where I Disagree
Where I disagree is when the discussion becomes:
Variables exist, therefore the flow should be redesigned.
That’s an oversimplification.
The existence of variables doesn’t always indicate bad architecture. What matters is why the variable exists.
Some values are static and some values change. Those are two different scenarios.
- If a value is calculated once and never changes, use a Compose with an expression.
- If a value changes throughout the execution of the flow, a variable may be the right solution.
Removing a variable only to replace it with an extremely complex expression isn’t always an improvement. Complex expressions carry their own maintenance cost.
Optimization shouldn’t only be measured by action counts.
It should also consider:
- Readability
- Supportability
- Handoff to future builders
- Ease of troubleshooting
- Ease of enhancement
A flow that saves two actions but takes twenty minutes to understand six months later isn’t necessarily better.
When Variables Are Absolutely Appropriate
There are several situations where variables solve a legitimate problem.
1. Incrementing counters inside loops
When processing records inside an Apply to each action, you may need to count:
- Number of approvals
- Number of survey responses
- Number of completed tasks
- Number of training sessions
The value changes during every loop iteration. A variable is the correct tool.
2. Accumulating totals
In my performance review flow, I needed to total metrics across many submitted records.
For example: Current Total + New Value
While incrementing a counter is focused on tracking how many times an event occurs, accumulating totals is focused on combining values across records. Instead of adding 1 during each iteration, you’re continuously adding varying amounts such as hours, dollars, minutes, scores, or other metrics until you reach a final total.
For example:
- Incrementing: Number of training classes delivered (1, 2, 3, 4…)
- Accumulated total: Total training hours delivered (2.5 + 4 + 1.5 + 3 = 11 hours)
That’s mutable state. Variables exist specifically for that purpose.
3. Building arrays
Sometimes you’re constructing a collection of information throughout a process.
For example:
- Email recipients
- Escalation paths
- Validation errors
- Summary records
A common example is collecting validation errors before sending a response back to a user. Rather than stopping the flow after the first issue is found, you can add each error message to an array as the flow evaluates different conditions:
Missing Project Name
Missing Due Date
Invalid Budget Amount
Manager Approval RequiredAt the end of the process, the array can be converted into a single email, Teams message, or approval comment showing everything that needs attention. This creates a much better user experience than forcing someone to fix one issue at a time.
Arrays are also useful when you need to build a collection of records throughout a flow. For example, you might loop through SharePoint items and create a summary array containing only the fields needed for a report, dashboard, or email. Once the loop is complete, the array can be used by a Select action, converted to an HTML table, or passed to another flow for additional processing.
Unlike a counter or accumulated total, where you’re updating a single value, an array variable allows you to continuously grow a collection of related information as the flow progresses. When the goal is to assemble a list of items that will be used later in the process, an array variable is often the most natural and maintainable solution.
4. Building strings
One of my most common uses for variables isn’t calculations at all. It’s assembling content over time.
In my performance review automation, I needed to include learner feedback comments inside a personalized HTML email. The challenge was that each employee could have anywhere from zero comments to dozens of comments.
At the beginning of the flow, I initialized a string variable called something like: DrewFeedbackCommentsHTML
Then inside an Apply to each loop, I append each comment as it was processed:
<li>INSERT DYNAMIC CONTENT HERE</li>By the time the loop finishes, I have a single HTML block ready to drop directly into the final email template.
I could have explored Select actions, array manipulation, or join expressions. But at some point, the “optimization” starts making the flow harder to understand than the original solution. Readability of a single variable in a loop has extreme value.
The key distinction is that the string is being built incrementally throughout the flow. Each iteration of the loop contributes something new to the final result. That’s exactly what variables are designed to do.
5. Tracking state across branches
This is one of the more overlooked uses for variables because it doesn’t happen in every flow.
Imagine an approval process.
Depending on the outcome of several conditions, a request may end up with one of the following statuses:
- Approved
- Rejected
- Sent Back for Revision
- Escalated
You could place separate actions in every branch and handle each case individually.
But often there’s a final action later that needs to know the overall result.
For example:
- Send final email
- Update SharePoint item
- Create audit log
- Post Teams notification
Instead of duplicating those actions in every branch, you can initialize a variable such as:
ApprovalStatus = PendingThen update it throughout the flow inside a Switch or Condition action.
At the end of the process, every action only needs to end with one value. The variable becomes the source of truth for the process.
I use this pattern frequently in Switch actions where different branches influence a single outcome. Rather than trying to remember which path was taken, the flow explicitly records it in a variable. Expressions become increasingly difficult when multiple paths can influence the same result.
Variables provide clarity because they make the current state visible. The flow is essentially documenting its own decision-making process.
That’s particularly valuable when troubleshooting. If something goes wrong, I can examine the variable and immediately understand what the flow believed its current state was when it reached that point.
6. Creating structured objects
This is where the LinkedIn discussion originally started and where I ended up building.
As my performance review flow grew, I found myself creating more and more related variables. Eventually I stepped back and realized I wasn’t really dealing with dozens of unrelated values. I was dealing with a single concept: Drew’s Performance Metrics.
The individual values were just properties of that concept. That’s what pushed me toward an object variable. Instead of dozens of separated variables, I created a structure like this:
{
"ReviewSnapshot": {
"SubmissionCount": 0,
"ReportingWeeks": 0,
"SubmissionConsistency": 0
},
"ExecutiveSummary": {
"Posts": 0,
"Videos": 0,
"StudyHours": 0
},
"ProfessionalContributions": {
"Comments": 0,
"Outreach": 0,
"PracticeExams": 0
}
}Instead of hunting through a long list of variables, I could immediately see:
- Review metrics
- Executive summary metrics
- Professional contribution metrics
All grouped together in one structure. The flow became easier for me to navigate.
For builders comfortable with JSON, this isn’t a huge problem. For someone newer to Power Automate, it’s a very different experience from selecting dynamic content from a panel.
That’s why I don’t think object variables are the perfect solution, they’re a workaround. A good workaround, but still a workaround.

What Too Many Variables Might Be Telling You
A high variable count isn’t inherently wrong. It is, however, worth investigating.
Too many variables may indicate:
- Repeated Logic: The same calculation appearing over and over may suggest a reusable structure
- Missing Child Flows: Large branches that perform similar work may benefit from reusable child flows
- Too Many Responsibilities: One flow sometimes grows into multiple business processes living inside the same automation
- Values That Could Be Compose Actions: A variable that never changes may be a Compose action with an expression
- Data Architecture Opportunities: Sometimes the underlying data structure is creating complexity that surfaces in the automation
The key word here is may. Variables are a signal to investigate, they are not proof something is wrong.
A Lesson from My Own Flow
Looking back at my performance review automation, there are things I would absolutely evaluate differently after my post.
For example, instead of maintaining three large employee scopes inside one flow, there’s a strong argument for separate flows.
Could that reduce complexity? Absolutely
Would it completely eliminate the need for variables? Not even close
The metrics still need to be accumulated, the survey data still needs to be summarized, the comments still need to be assembled into a bulleted list, the values still need to change while the flow runs.
Object Variables Aren’t Beginner Friendly
Object variables solve one problem by creating another.
To reference a value, you now need expressions like:
variables('DrewMetrics')?['SurveyResponses']Or nested references like:
variables('DrewMetrics')?['ExecutiveSummary']?['Posts']To update values you often need expressions such as:
setProperty(
variables('DrewSessionTypeSummary'),
outputs('Compose_-_Current_Session_Type'),
add(
int(outputs('Compose_-_Current_Session_Type_Count')),
1
)
)None of this is particularly difficult if you’re comfortable with JSON. But it moves builders away from Power Automate’s visual authoring experience and into coding and complex expression writing.
For experienced makers, that’s often fine. For beginners, it can feel like an entirely different product that’s out of reach.
What I Wish Power Automate Would Do Instead
My original post wasn’t actually advocating for more variables. It was advocating for a better variable experience.
Imagine an Initialize (Batch) Variables action that allows makers to:
- Create groups
- Define multiple variables at once
- Set types and default values
- Search variables
- Import a schema
- Collapse sections
- Organize related data visually
Under the hood, Microsoft can implement this however they want, whether it’s one object or multiple variables.
What I care about is preserving Power Automate’s low-code experience.
The Real Takeaway
The LinkedIn discussion reinforced something I’ve believed for a long time:
Power Automate design decisions shouldn’t become absolutes.
Variables aren’t inherently bad. Compose actions aren’t inherently better. Object variables aren’t superior.
Every approach involves tradeoffs that the maker decides to take on.
My recommendation is this:
- Use direct references when a value already exists
- Use Compose when a value is calculated once and doesn’t change
- Use variables when a value must change over time.
- Use object variables when grouping related mutable data provides organizational value
- Review flows with large numbers of variables, but don’t assume they’re wrong
If a variable serves a legitimate purpose, removing it isn’t optimization. It’s just moving that complexity somewhere else.