Canvas Apps Performance

How to make concurrent multiple unrelated data calls

Database calls

Introduction

A lot of times, you make multiple unrelated data calls (calls that have no dependencies on each other) in one go. For example, App OnStart or Onvisible of a splash screen are very common places where this is done.

Non-concurrent calls

One way to do that is to write all those calls separated by ; as shown below:

Set(
    gblUserTitle,
    LookUp(
        Users,
        'Primary Email' = User().Email,
        Title
    )
);
With(
    {
        varUser: First(
            SortByColumns(
                Filter(
                    Users,
                    'First Name' = "Hardit"
                ),
                "createdon",
                SortOrder.Descending
            )
        )
    },
    Patch(
        Users,
        varUser,
        {'Main Phone': "9876543210"};
    )
);
Set(
    gblUserMainPhone,
    LookUp(
        Users,
        'Primary Email' = User().Email
    ).'Main Phone'
);
Set(
    gblUserMobilePhone,
    LookUp(
        Users,
        'Primary Email' = User().Email
    ).'Mobile Phone'
);
Set(
    gblUserUserName,
    LookUp(
        Users,
        'Primary Email' = User().Email
    ).'User Name'
);
Set(
    varFunctionAppURL,
    LookUp(
        'Environment Variable Values',
        'Environment Variable Definition'.'Schema Name' = "FunctionAppURL",
        Value
    )
);
Set(
    varAPIURL,
    LookUp(
        'Environment Variable Values',
        'Environment Variable Definition'.'Schema Name' = "ApiUrl",
        Value
    )
);
Set(
    varAPIMTeamsBaseURL,
    LookUp(
        'Environment Variable Values',
        'Environment Variable Definition'.'Schema Name' = "APIMTeamsBaseURL",
        Value
    )
);

Concurrent calls

Another way to do it is to combine these calls inside the Concurrent function as shown below:

Concurrent(
    Set(
        gblUserTitle,
        LookUp(
            Users,
            'Primary Email' = User().Email,
            Title
        )
    ),
    With(
        {
            varUser: First(
                SortByColumns(
                    Filter(
                        Users,
                        'First Name' = "Hardit"
                    ),
                    "createdon",
                    SortOrder.Descending
                )
            )
        },
        Patch(
            Users,
            varUser,
            {'Main Phone': "9876543210"};
        )
    ),
    Set(
        gblUserMainPhone,
        LookUp(
            Users,
            'Primary Email' = User().Email
        ).'Main Phone'
    ),
    Set(
        gblUserMobilePhone,
        LookUp(
            Users,
            'Primary Email' = User().Email
        ).'Mobile Phone'
    ),
    Set(
        gblUserUserName,
        LookUp(
            Users,
            'Primary Email' = User().Email
        ).'User Name'
    ),
    Set(
        varFunctionAppURL,
        LookUp(
            'Environment Variable Values',
            'Environment Variable Definition'.'Schema Name' = "FunctionAppURL",
            Value
        )
    ),
    Set(
        varAPIURL,
        LookUp(
            'Environment Variable Values',
            'Environment Variable Definition'.'Schema Name' = "ApiUrl",
            Value
        )
    ),
    Set(
        varAPIMTeamsBaseURL,
        LookUp(
            'Environment Variable Values',
            'Environment Variable Definition'.'Schema Name' = "APIMTeamsBaseURL",
            Value
        )
    )
)

The main advantage of using the Concurrent function is that all data calls are made at the same time. On the other hand, in approach 1, each data call is made when the previous one gets finished.

Here is an image of the monitor tool showing the difference in times taken for these 2 approaches:

Difference in time taken with and without Concurrent function

In the 1st approach, the total time taken for all calls to end (which is the sum of all individual calls) is from 15:38:38.115 to 15:38:38.787 which is 672 milliseconds which is approximately the sum of duration for each data call.

In the 2nd approach. although the individual calls have taken more times than in the 1st approach, the total duration is actually less. The time taken for all calls to end is from 15:40:13:889 to 15:40:14:282 which is 393 milliseconds. That is approximately half of the duration in the 1st approach.

Recent articles

  1. How to optimize fetching multiple records from a table
  2. How to optimize passing a record to Patch
  3. Optimize fetching multiple columns of a record

2 thoughts on “How to make concurrent multiple unrelated data calls”

Leave a Reply