Iterating over an array of values to perform complex actions is easy with actions such as Apply to Each or Do Until within Power Automate.
But what if you simply want to concatenate some strings together? Or sum some numbers? Or do some other simplistic x, y, or z logic?
I already know about loops, take me to the goods! (tl;dr)
Here’s an example of a loop to sum an array of 15 numbers: [1,2,3,4,5,6,7,8,9,10,0.1,0.2,0.3,0.4,0.5]

As you can see from the image above, even for relative simple operations, these looping actions can actually be quite expensive performance-wise for your flow. Four seconds or more to sum 15 numbers? Yikes. (I’ve even seen it take 6+ seconds, not good.)
Plus, loops can be hard to troubleshoot when things go wrong. How frustrating is it when you can’t expand the loop action or any of its children to see what the loop is currently doing while it’s running?

That’s unfortunate, we can’t see what the loop is currently doing.
So, do I really need a loop?
Maybe, maybe not.
Going back to our inefficient number sum example above. Let’s think about how we can approach this a different way.
Here’s what we know:
- We have an array of values (numbers)
- We need a single output (sum)
- We don’t want to use a loop
Since we are dealing with an array (aka collection), the first thing to do is to see which actions and/or expressions we have that can target them.
Under the Data Operation category of the Power Automate actions list, there are some possible action candidates: Filter
, Select
, and Join
which all deal with arrays. Although only one returns a single value, Join.

Join still is not what we need as it simply concatenates values together into a single string. It doesn’t allow us to do any math operations, like we need for summing numbers.
Next, let’s look at the expressions we have available in the dynamic content panel. Some possible candidates are: concat
, union
, join
, add
.


Ooh … add, but shucks it only takes 2 parameters, and array has 15 values. That won’t work.
Wait … here’s an interesting expression: xpath(...)
. What’s XPath?
XPath is an expression language that navigates and selects nodes in an XML document.
This sounds very similar to what a loop can do. Alright, we may be on to something here! Can XPath sum values? Why yes it can!
Expressions to the rescue!
Using XPath against our array requires us to convert it XML. This is easy with the xml(...)
expression.
Unfortunately, arrays don’t directly convert to XML, so we need to massage it slightly.
XML expects a single element at the root of the document, and arrays are multiple elements. So we can simply wrap our array in a JSON object to accomplish this.
Assuming our array of numbers is in a compose action like this:

Here’s the expression to wrap our number array:
json(concat('{"r":{"v":', outputs('Numbers'), '}}')))
Which produces this new object:
{
"r": {
"v": [1,2,3,4,5,6,7,8,9,10,0.1,0.2,0.3,0.4,0.5]
}
}
With this new JSON object, “r” is now the root property, and it looks like this when we convert it to XML:
<r><v>1</v><v>2</v><v>3</v><v>4</v><v>5</v><v>6</v><v>7</v><v>8</v><v>9</v><v>10</v><v>0.1</v><v>0.2</v><v>0.3</v><v>0.4</v><v>0.5</v></r>
Now the XPath needed to sum the values looks like this:
sum(//v/text()[number(.) = number(.)])
Here’s what it is doing:
sum(...)
– this function adds element values together (our numbers),//v/text()
– this selects all of the elements, the “v” nodes (our numbers), and returns their text value,number(.) = number(.)
– this logic basically means “only when the value, converted to a number, equals a number” or something like that.
So, the complete XPath sum expression looks like this:
xpath(xml(json(concat('{"r":{"v":', outputs('Numbers'), '}}'))), 'sum(//v/text()[number(.) = number(.)])')
Here’s the output of the run of this flow action:

Zero seconds! That’s better.
And if you really want to see the time differences, here are the metrics, using the start/end times of the actions:

Tip to calculate how long an action took to execute (in seconds), use this expression:
div(sub(ticks(actions('XPath_Sum')?['endTime']),ticks(actions('XPath_Sum')?['startTime'])),float(10000000))
Takeaway
As you can see, using XPath is blazingly fast compared to the loop timing.
And as you increase the number of items, the loop tends to get slower, but XPath generally does not.
For example, summing a range of numbers 1 to 100: range(1, 100)


Loops aren’t always necessary and can be a performance hog when used unnecessarily.
I encourage you, spend a little forethought on what your flow will do, and you can have it do mighty things, simpler and faster.
See my next post on how to generate cleaner concatenated strings using XPath.
Happy coding!
Follow My Blog
Get new content delivered directly to your inbox.