# A little help with \`Io\` please. I am trying to understand how to use the new \`Io\` interface for Zig

**URL:** <https://ziggit.dev/t/a-little-help-with-io-please-i-am-trying-to-understand-how-to-use-the-new-io-interface-for-zig/14006>\
**Category:** Brainstorming\
**Tags:** language, io\
**Created:** [January 20, 2026, 7:26am UTC](https://ziggit.dev/t/a-little-help-with-io-please-i-am-trying-to-understand-how-to-use-the-new-io-interface-for-zig/14006 "2026-01-20T07:26:55Z")\
**Posts on this page:** 9\
**Page:** 2

<div class="post-metadata">

**Author:** ![lalinsky](https://ziggit.dev/user_avatar/ziggit.dev/lalinsky/32/3720_2.png) [@lalinsky](https://ziggit.dev/u/lalinsky)\
**Post date:** [January 24, 2026, 7:14pm UTC](https://ziggit.dev/t/a-little-help-with-io-please-i-am-trying-to-understand-how-to-use-the-new-io-interface-for-zig/14006/21 "2026-01-24T19:14:26Z")

</div>

You are mistaken, `io.async` indeed can block execution, that’s the main purpose. There is no guarantee the function called from `io.async` is going to run concurrently. You need to use `io.concurrent` there.

However, for long sleeps, especially for something lie sleeping for half a day until certain time, you definitely don’t want an idle thread just for that.

---

<div class="post-metadata">

**Author:** ![mnemnion](https://ziggit.dev/user_avatar/ziggit.dev/mnemnion/32/2478_2.png) [@mnemnion](https://ziggit.dev/u/mnemnion)\
**Post date:** [January 24, 2026, 7:26pm UTC](https://ziggit.dev/t/a-little-help-with-io-please-i-am-trying-to-understand-how-to-use-the-new-io-interface-for-zig/14006/22 "2026-01-24T19:26:54Z")

</div>

Welcome to the forum @colorpalette!

Let’s make that feedback a little bit more useful, shall we?

Your comment that says it will wait three seconds: that depends on the `Io` implementation which is used. It’s allowed to block, in which case, it would be four seconds.

Concurrent would cause a runtime error if the two sleeps cannot be run in parallel. Don’t use it unless the code requires that property.

---

<div class="post-metadata">

**Author:** ![colorpalette](https://ziggit.dev/letter_avatar_proxy/v4/letter/c/22d042/32.png) [@colorpalette](https://ziggit.dev/u/colorpalette)\
**Post date:** [January 24, 2026, 7:39pm UTC](https://ziggit.dev/t/a-little-help-with-io-please-i-am-trying-to-understand-how-to-use-the-new-io-interface-for-zig/14006/23 "2026-01-24T19:39:55Z")

</div>

@lalinsky Thanks for pointing that out, I neglected to make the distinction between functions which yield execution and functions which block. I’ve updated the comment now, can probably be worded more accurately and have better and more detailed examples.

@mnemnion Thanks, I’ve been lurking for quite some time and finally signed up. You’re right about being specific about the `Io` implementation and the different behaviors you can get from the same code depending on which one is used. I was exploring with a standard `Threaded` io with multiple cores and jumped to conclusions too quickly. I think the current example is useful for a javascript developer to get an initial idea of the parallels between js and zig’s asynchrony, but I definitely need to update this demo to make it more correct.

---

<div class="post-metadata">

**Author:** ![lalinsky](https://ziggit.dev/user_avatar/ziggit.dev/lalinsky/32/3720_2.png) [@lalinsky](https://ziggit.dev/u/lalinsky)\
**Post date:** [January 24, 2026, 7:58pm UTC](https://ziggit.dev/t/a-little-help-with-io-please-i-am-trying-to-understand-how-to-use-the-new-io-interface-for-zig/14006/24 "2026-01-24T19:58:57Z")

</div>

> [@colorpalette](#):
>
> I’ve updated the comment now, can probably be worded more accurately and have better and more detailed examples.

The key part is that you should use `io.concurrent` in the example. Then it would be correct. As is, the behavior depends on a chance.

---

<div class="post-metadata">

**Author:** ![Illusion](https://ziggit.dev/letter_avatar_proxy/v4/letter/i/e19b73/32.png) [@Illusion](https://ziggit.dev/u/Illusion)\
**Post date:** [January 24, 2026, 8:05pm UTC](https://ziggit.dev/t/a-little-help-with-io-please-i-am-trying-to-understand-how-to-use-the-new-io-interface-for-zig/14006/25 "2026-01-24T20:05:13Z")

</div>

Just thinking out loud: I’m trying to think of what situations that would be useful (outside of accepting connections). E.g., at least in business logic style work, if you have tasks A, B, and C, it is optimal is A, B, and C run concurrently, but it’s not strictly a requirement. It just needs to be done. So you’d just use io.async, I presume. Similarly, even in more complex use cases where you have some degree of enforcement on ordering (e.g. a DAG), once again you would use io.async as, you only need to block execution until all ancestors complete, which can be accomplished in order as opposed to in parallel. E.g. in the Python context

```zig
import graphlib
import asyncio

sorter = graphlib.TopologicalSorter(dag)
in_flight = {}
while sorter.is_active():
    for node in sorter.get_ready():
        task = asyncio.create_task(some_f, node)
        in_flight[task] = node

    done_or_cancelled, not_done = asyncio.wait(in_flight.keys(), timeout=10, return_when=asyncio.FIRST_COMPLETED)
    for task in done_or_cancelled:
        if task.cancelled():
            pass # do whatever reconciliation is needed
        else:
            node = in_flight.pop(task)
            sorter.done(node)

```

Summary being, it seems io.concurrent is very specific.

---

<div class="post-metadata">

**Author:** ![lalinsky](https://ziggit.dev/user_avatar/ziggit.dev/lalinsky/32/3720_2.png) [@lalinsky](https://ziggit.dev/u/lalinsky)\
**Post date:** [January 24, 2026, 8:17pm UTC](https://ziggit.dev/t/a-little-help-with-io-please-i-am-trying-to-understand-how-to-use-the-new-io-interface-for-zig/14006/26 "2026-01-24T20:17:55Z")

</div>

> [@Illusion](#):
>
> I’m trying to think of what situations that would be useful

Anything that deals with timing can’t realistically use `io.async`, because you don’t now the final sleep time.

Another class of problems is using `Io.Queue` or similar synchronization mechanisms. If you want to call a function that puts items to the queue and you process them after that, you need to call the function using `io.concurrent`, using `io.async` might deadlock the program. This similar to your A, B, C example. As soon as you have any kind of dependency between them, running them using `io.async` is dangerous.

For me, `io.async` is basically the tool to use when I have linear blocking code, and part of the _could_ benefit from being concurrent, but it was linear blocking code to begin with.

---

<div class="post-metadata">

**Author:** ![Illusion](https://ziggit.dev/letter_avatar_proxy/v4/letter/i/e19b73/32.png) [@Illusion](https://ziggit.dev/u/Illusion)\
**Post date:** [January 24, 2026, 8:56pm UTC](https://ziggit.dev/t/a-little-help-with-io-please-i-am-trying-to-understand-how-to-use-the-new-io-interface-for-zig/14006/27 "2026-01-24T20:56:07Z")

</div>

Isn’t that where timeouts come in for tasks? In the A, B, C example they’re all independent, hence, say your underlying IO is single-threaded, so long as you have timeouts, once A exceeds its timeout, you move onto B, etc. etc.

Same in the DAG example, if you reach a point where there are no more processable nodes and those next in line have parents in error, you know to quit at that point and propagate the collection of errors to the user along with their DAG state.

My only real point was, there’s: “it would be nice if this runs concurrently” (i.e. business logic stuff where you make HTTP requests) vs. “this needs to be concurrent” (i.e. your server has to be running and accepting connections). io.concurrent seems specific for the latter.

---

<div class="post-metadata">

**Author:** ![lalinsky](https://ziggit.dev/user_avatar/ziggit.dev/lalinsky/32/3720_2.png) [@lalinsky](https://ziggit.dev/u/lalinsky)\
**Post date:** [January 24, 2026, 8:59pm UTC](https://ziggit.dev/t/a-little-help-with-io-please-i-am-trying-to-understand-how-to-use-the-new-io-interface-for-zig/14006/28 "2026-01-24T20:59:13Z")

</div>

> [@Illusion](#):
>
> Isn’t that where timeouts come in for tasks? In the A, B, C example they’re all independent, hence, say your underlying IO is single-threaded, so long as you have timeouts, once A exceeds its timeout, you move onto B, etc. etc.

Timeout is a good example, `std.Io` doesn’t have timeouts for most operations, so the way you would do that is using `io.concurrent` for a sleep, `io.concurrent` for the task and then `io.select` on them. If you used `io.async` instead, you would end up in a situation where the sleep could run sequentially before or after the task.

---

<div class="post-metadata">

**Author:** ![jmctagger](https://ziggit.dev/letter_avatar_proxy/v4/letter/j/8dc957/32.png) [@jmctagger](https://ziggit.dev/u/jmctagger)\
**Post date:** [January 25, 2026, 8:56am UTC](https://ziggit.dev/t/a-little-help-with-io-please-i-am-trying-to-understand-how-to-use-the-new-io-interface-for-zig/14006/29 "2026-01-25T08:56:49Z")

</div>

> [@lalinsky](#):
>
> For me, `io.async` is basically the tool to use when I have linear blocking code, and part of the _could_ benefit from being concurrent, but it was linear blocking code to begin with.

This is how I’ve always thought about async/await, language-independent. Notably: there’s a certain independence between the tasks that “could be run linearly… but _could_ benefit from coincidental asynchrony”. No interdependence - that gets dangerous, and is not a good fit. `io.concurrent` is the choice if you _need_ concurrency.

[Previous page](https://ziggit.dev/t/a-little-help-with-io-please-i-am-trying-to-understand-how-to-use-the-new-io-interface-for-zig/14006.md?page=1)
