Skip to main content

Enjoy faster startup times with the new Concurrent function

Headshot of article author Greg Lindhorst

Do your apps pre-load a bunch of data when they start, typically in the OnStart formula?  Collect, after Collect, after Collect, loading up tables of data so that when your user interacts with the app it is ready to go?

Until now, we did this by using the chaining operator ; (or ;; depending on your language) which would perform multiple actions in sequence.  For example, if we wanted to pre-load some tables from the Adventure Works database in SQL Azure, we might have written:

        ClearCollect( Product, '[SalesLT].[Product]' );
        ClearCollect( Customer, '[SalesLT].[Customer]' );
        ClearCollect( SalesOrderDetail, '[SalesLT].[SalesOrderDetail]' );
        ClearCollect( SalesOrderHeader, '[SalesLT].[SalesOrderHeader]' )

If we watch this formula in action with a network monitor, we see this kind of pattern:

image

One at a time, the next one doesn't start until the last one is complete, one lane of traffic.  What if we could have multiple lanes of traffic?  What if we could perform these operations concurrently, in parallel? 

Enter the Concurrent function.  Take those exact same four ClearCollect calls above and place them within this function:

        Concurrent(
                ClearCollect( Product, '[SalesLT].[Product]' ),
                ClearCollect( Customer, '[SalesLT].[Customer]' ),
                ClearCollect( SalesOrderDetail, '[SalesLT].[SalesOrderDetail]' ),
                ClearCollect( SalesOrderHeader, '[SalesLT].[SalesOrderHeader]' )
        )

And that’s all it takes to parallelize the requests:

image

These graphs are on the same scale, and oh my, the overall wait time has been reduced by about half.  Let me say that again half the time!  The resulting collections are exactly the same.

You can read more about Concurrent in the reference

As with any parallel processing, the main thing to watch out for is dependencies between the formulas as we can't know which one will finish first and it might change from run to run.  PowerApps will detect and report errors for dependencies that it can detect, for example reading and writing a variable.  But dependencies can be subtle and undetectable if you are making service calls or running Flows that have side effects.