# Calling several futures in parallel (in Motoko)

**URL:** <https://forum.dfinity.org/t/calling-several-futures-in-parallel-in-motoko/20058>\
**Category:** Motoko\
**Created:** [May 17, 2023, 1:38pm UTC](https://forum.dfinity.org/t/calling-several-futures-in-parallel-in-motoko/20058 "2023-05-17T13:38:17Z")\
**Posts on this page:** 16\
**Page:** 1

<div class="post-metadata">

**Author:** ![qwertytrewq](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/qwertytrewq/32/10423_2.png) [@qwertytrewq](https://forum.dfinity.org/u/qwertytrewq)\
**Post date:** [May 17, 2023, 1:38pm UTC](https://forum.dfinity.org/t/calling-several-futures-in-parallel-in-motoko/20058/1 "2023-05-17T13:38:17Z")

</div>

In JavaScript there is `Promise.all` to wait at once for several futures. Is there (or can be implemented?) a similar thing in Motoko?

I want to wait for `skExists` from several CanDB canisters to securely check whether a key exists in the CanDB DB. Is it possible?

---

<div class="post-metadata">

**Author:** ![claudio](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/claudio/32/322_2.png) [@claudio](https://forum.dfinity.org/u/claudio)\
**Post date:** [May 17, 2023, 5:10pm UTC](https://forum.dfinity.org/t/calling-several-futures-in-parallel-in-motoko/20058/2 "2023-05-17T17:10:00Z")

</div>

There is no Promise.all in Motoko and it’s currently not possible to author a fully generic one.

However, you can do parallel waiting by issuing several sends and only awaiting the results later.

‘’’  
let p1 = a1.send();  
let p2 = a2.send();  
let r1 = await p1;  
let r2 = await p2;  
‘’’

---

<div class="post-metadata">

**Author:** ![qwertytrewq](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/qwertytrewq/32/10423_2.png) [@qwertytrewq](https://forum.dfinity.org/u/qwertytrewq)\
**Post date:** [May 17, 2023, 6:32pm UTC](https://forum.dfinity.org/t/calling-several-futures-in-parallel-in-motoko/20058/3 "2023-05-17T18:32:47Z")

</div>

No, @claudio , your code first blocks on `await p1` and only then moves to `await p2`.

Probably, this will work:

```auto
let p1 = a1.send();
let p2 = a2.send();
let r = [await p1, await p2];

```

But I am unsure even on the last code.

---

<div class="post-metadata">

**Author:** ![quint](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/quint/32/40449_2.png) [@quint](https://forum.dfinity.org/u/quint)\
**Post date:** [May 17, 2023, 7:17pm UTC](https://forum.dfinity.org/t/calling-several-futures-in-parallel-in-motoko/20058/4 "2023-05-17T19:17:13Z")

</div>

That is exactly how a `Promise.all` works.  
You will only be waiting as long as the longest call.

Either `p1` takes longer, than you do not need to wait on `p2`.  
Or `p1` finishes and you will also have to wait for `p2`.

There is no real difference between:

> [@claudio](#):
>
> ```auto
> let r1 = await p1;
> let r2 = await p2;
> 
> ```

> [@qwertytrewq](#):
>
> ```auto
> let r = [await p1, await p2];
> 
> ```

---

<div class="post-metadata">

**Author:** ![qwertytrewq](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/qwertytrewq/32/10423_2.png) [@qwertytrewq](https://forum.dfinity.org/u/qwertytrewq)\
**Post date:** [May 17, 2023, 7:44pm UTC](https://forum.dfinity.org/t/calling-several-futures-in-parallel-in-motoko/20058/5 "2023-05-17T19:44:32Z")

</div>

@claudio You seem to think that

```auto
let r1 = await p1;
let r2 = await p2;

```

executes in parallel.

That’s not the case! `await` like any other language construct is executed sequentially.

`await p1` blocks that is not allows to execute any more code in this thread of control until `p1` finished. Only then `await p2` is executed.

I will present another example to illustrate my point:

```auto
let r1 = await p1;
Debug.print("in the middle");
let r2 = await p2;

```

If `await p2` executed in parallel with `await p1`, then `in the middle` would be printed after `await p2`, not before. That’s not the case.

---

<div class="post-metadata">

**Author:** ![qwertytrewq](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/qwertytrewq/32/10423_2.png) [@qwertytrewq](https://forum.dfinity.org/u/qwertytrewq)\
**Post date:** [May 17, 2023, 7:47pm UTC](https://forum.dfinity.org/t/calling-several-futures-in-parallel-in-motoko/20058/6 "2023-05-17T19:47:10Z")

</div>

@claudio Oh, I misunderstood you:

```auto
await p1;
await p2;

```

is really equivalent to `Promise.all` in JavaScript, because it finishes as soon as both `p1` and `p2` finish.

---

<div class="post-metadata">

**Author:** ![qwertytrewq](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/qwertytrewq/32/10423_2.png) [@qwertytrewq](https://forum.dfinity.org/u/qwertytrewq)\
**Post date:** [May 17, 2023, 8:23pm UTC](https://forum.dfinity.org/t/calling-several-futures-in-parallel-in-motoko/20058/7 "2023-05-17T20:23:13Z")

</div>

@claudio

However, no:

`a1.send()` does not start execution of an async function `a1.send`, it just returns a future (if Motoko works the same as most asynchronous languages).

So, in

```auto
let p1 = a1.send();
let p2 = a2.send();
let r1 = await p1;
let r2 = await p2;

```

execution of `a2` starts only after execution of `a1` finishes.

---

<div class="post-metadata">

**Author:** ![claudio](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/claudio/32/322_2.png) [@claudio](https://forum.dfinity.org/u/claudio)\
**Post date:** [May 17, 2023, 9:18pm UTC](https://forum.dfinity.org/t/calling-several-futures-in-parallel-in-motoko/20058/8 "2023-05-17T21:18:49Z")

</div>

Both messages are enqueued at send() and actually both sent at the first await. If destined at two different receivers, they can execute concurrently and, after the second await, will both have finished.

Motoko futures are eager, not lazy. Even if you don’t await a future, its effects still happen.

---

<div class="post-metadata">

**Author:** ![jeshli](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/jeshli/32/19879_2.png) [@jeshli](https://forum.dfinity.org/u/jeshli)\
**Post date:** [January 6, 2024, 7:04pm UTC](https://forum.dfinity.org/t/calling-several-futures-in-parallel-in-motoko/20058/9 "2024-01-06T19:04:47Z")

</div>

Thanks for sharing this. It is extremely helpful. Can you confirm that Canisters written in Rust will behave the same way?

---

<div class="post-metadata">

**Author:** ![claudio](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/claudio/32/322_2.png) [@claudio](https://forum.dfinity.org/u/claudio)\
**Post date:** [January 6, 2024, 11:31pm UTC](https://forum.dfinity.org/t/calling-several-futures-in-parallel-in-motoko/20058/10 "2024-01-06T23:31:02Z")

</div>

@mraszyk might be able to answer about the Rust cdk. I believe it originally used eager semantics, but may since changed to lazy. Don’t trust my answer.

---

<div class="post-metadata">

**Author:** ![mraszyk](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/mraszyk/32/7945_2.png) [@mraszyk](https://forum.dfinity.org/u/mraszyk)\
**Post date:** [January 7, 2024, 2:03pm UTC](https://forum.dfinity.org/t/calling-several-futures-in-parallel-in-motoko/20058/11 "2024-01-07T14:03:15Z")

</div>

> I believe it originally used eager semantics, but may since changed to lazy.

Indeed, inter-canister calls in Rust (using `ic_cdk::call`) won’t be executed unless they’re awaited (this is standard in Rust and the Rust compiler issues warnings if a future is not awaited). To execute multiple inter-canister calls in parallel in Rust, you can do the following:

```auto
        let mut futs = vec![];
        for i in 0..4 {
            futs.push(call(my_favorite_canister, "foo", ((i),)));
        }
        let res: Vec<Result<(u64,), _>> = join_all(futs).await;

```

---

<div class="post-metadata">

**Author:** ![jeshli](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/jeshli/32/19879_2.png) [@jeshli](https://forum.dfinity.org/u/jeshli)\
**Post date:** [January 7, 2024, 8:46pm UTC](https://forum.dfinity.org/t/calling-several-futures-in-parallel-in-motoko/20058/12 "2024-01-07T20:46:51Z")

</div>

Thank you very much for this example! I’m very excited to apply it to my work.

It seems in your example that you push to `my_favorite_canister` each time. Since this is the same canister, would it prevent the process from being parallelized? Would I have to call a distinct canister for each pushed call for it to be parallelized? Would queries be parallelizable to the same canister because it could go to a different node, but updates not? TIA

---

<div class="post-metadata">

**Author:** ![Samer](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/samer/32/8943_2.png) [@Samer](https://forum.dfinity.org/u/Samer)\
**Post date:** [January 7, 2024, 11:49pm UTC](https://forum.dfinity.org/t/calling-several-futures-in-parallel-in-motoko/20058/13 "2024-01-07T23:49:35Z")

</div>

This might also be helpful  
[https://web3.motoko-book.dev/advanced-concepts/async-programming.html](https://web3.motoko-book.dev/advanced-concepts/async-programming.html)

---

<div class="post-metadata">

**Author:** ![mraszyk](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/mraszyk/32/7945_2.png) [@mraszyk](https://forum.dfinity.org/u/mraszyk)\
**Post date:** [January 8, 2024, 9:29am UTC](https://forum.dfinity.org/t/calling-several-futures-in-parallel-in-motoko/20058/14 "2024-01-08T09:29:50Z")

</div>

> It seems in your example that you push to `my_favorite_canister` each time. Since this is the same canister, would it prevent the process from being parallelized? Would I have to call a distinct canister for each pushed call for it to be parallelized?

Indeed, calls to the same canister are executed sequentially by the IC. Hence, you’d need to call distinct canisters to benefit from concurrent execution of the calls. But you might already get some speed up when calling the same canister as I showed above since the calls will (very likely) be executed in a batch on the same thread without other canisters being executed on that thread in between.

> Would queries be parallelizable to the same canister because it could go to a different node, but updates not?

No, to preserve the security guarantees of the IC, if you invoke a query method from an update call, then this query method is executed on all nodes just like an update call to an update method.

---

<div class="post-metadata">

**Author:** ![jeshli](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/jeshli/32/19879_2.png) [@jeshli](https://forum.dfinity.org/u/jeshli)\
**Post date:** [January 8, 2024, 2:56pm UTC](https://forum.dfinity.org/t/calling-several-futures-in-parallel-in-motoko/20058/15 "2024-01-08T14:56:04Z")

</div>

Thank you very much for the detailed response. This has all been very helpful and I am eager to integrate it into my code. I have one last question to help me understand the best course for my architecture.

> [@mraszyk](#):
>
> No, to preserve the security guarantees of the IC, if you invoke a query method from an update call, then this query method is executed on all nodes just like an update call to an update method.

Would using Composite\_Query to invoke Queries require the same “security guarantee”? Could a Composite Query have more than one Query concurrently executed by the same Canister on different nodes?

---

<div class="post-metadata">

**Author:** ![mraszyk](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/mraszyk/32/7945_2.png) [@mraszyk](https://forum.dfinity.org/u/mraszyk)\
**Post date:** [January 8, 2024, 3:28pm UTC](https://forum.dfinity.org/t/calling-several-futures-in-parallel-in-motoko/20058/16 "2024-01-08T15:28:22Z")

</div>

> Would using Composite\_Query to invoke Queries require the same “security guarantee”?

No, the security guarantees of both query calls and composite query calls are weaker than the security guarantees of update calls since both query calls and composite query calls are executed by only one node.

> Could a Composite Query have more than one Query concurrently executed by the same Canister on different nodes?

No, all individual queries executed as part of a composite query evaluation are evaluated on the same node that received the original composite query call.
