Can you make multiple inter-canister calls in parallel in Motoko?

Is it possible to make multiple inter-canister calls and then await for all the responses. For example, a canister makes numerous calls to other canisters in parallel, and waits for all the calls to finish. And it only takes the time it would take for 1 inter-canister call since they’re all being done in parallel. I’m trying to do this in Motoko, is there sample code that shows how this can be done?

1 Like

I have this in one of my canisters:

    while (create_n > 0) {
      ignore create_canister_to_reserve(Nat64.fromIntWrap(create_n));
      create_n := create_n - 1;
    };

create_canister_to_reserve is an async function.

If you don’t ignore but instead collect the futures I would assume(!) the calls get executed in parallel and you can await all of them afterwards. Please let me know if that works

2 Likes

The call to a function with async result type returns an async value (sometimes called a future). Awaiting the contents of that value is a completely separate operation, that can be done at any later point in the function. Simplest possible example:

func caller() {
    let r1 = f1();      // async call
    let r2 = f2();      // async call, in parallel
    let v1 = await r1;  // now wait for both
    let v2 = await r2;
    ...
}
2 Likes

@Severin @rossberg Thanks for the quick responses! Super helpful, will try these solutions out and let you know :+1:

This might also be helpful

https://web3.motoko-book.dev/advanced-concepts/async-programming.html

1 Like

One word of warning(and maybe a question), but your ability to do this maybe limited to what canister your calling, where it lives, and how cycle accounting works.

Each call does(I think) register some cycle hit…if it is a canister on another subnet(like the ICP canister for example) it may incur MORE of a hit. In the past, I’ve batched and had success with like 9 at a time:

1 Like