Zio - async I/O framework

I’m not sure I understand, if this is user-space std.Io impl, then why is it a problem, why it should ever go away? I haven’t tried yet so I might be missing something but surely your project looks very compelling :slight_smile:

Zio is a backend with two frontend APIs, you can use e.g. zio.net.Stream or std.Io.net.Stream. The former is what I call native and it existed before std.Io was a thing.

2 Likes

congrats, as far as I know this is the first functioning third-party Io implementation

10 Likes

Running zig build examples fails:

examples
└─ install ev-demo
   └─ compile exe ev-demo Debug native 2 errors
error: fatal linker error: unhandled relocation type R_X86_64_PC64 at offset 0x1c
    note: in /usr/lib/gcc/x86_64-pc-linux-gnu/16.1.1/../../../../lib/crt1.o:.sframe
error: fatal linker error: unhandled relocation type R_X86_64_PC64 at offset 0x2c
    note: in /usr/lib/gcc/x86_64-pc-linux-gnu/16.1.1/../../../../lib/crt1.o:.sframe
error: 2 compilation errors

I used:

/c/g/g/l/zio ((v0.11.0)) [1]> zig-0.16.0 build examples

Try with -Doptimize=ReleaseSafe.

Hm, apparently the fix is to use lld, never hit this myself.

https://codeberg.org/ziglang/zig/issues/31272

@gonzo, Thanks, it works.

I tried to run the example from
https://lalinsky.com/2026/05/11/async-io-in-zig-016-today.html
with const num_tasks = 10_000_000;

The output was:

manlio@mini-linux /t/zigtmp> time ./zig-out/bin/zigtmp
error(zio): Failed to commit initial stack region: error.OutOfMemory
thread 15745 panic: reached unreachable code
Unwind error at address `???:0x102a5b1` (out of memory), remaining frames may be incorrect
Ran out of memory loading debug info, trace may be incomplete

???:?:?: 0x1081c71 in ??? (???)
Ran out of memory loading debug info, trace may be incomplete

???:?:?: 0x1029fb3 in ??? (???)
Ran out of memory loading debug info, trace may be incomplete

???:?:?: 0x7ff6bc827740 in ??? (???)
Ran out of memory loading debug info, trace may be incomplete

???:?:?: 0x7ff6bc827878 in ??? (???)
Ran out of memory loading debug info, trace may be incomplete

???:?:?: 0x10270d4 in ??? (???)
^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C
________________________________________________________
Executed in  118.34 secs    fish           external
   usr time    0.44 secs  532.00 micros    0.44 secs
   sys time   17.18 secs  402.00 micros   17.18 secs

fish: Job 1, 'time ./zig-out/bin/zigtmp' terminated by signal SIGKILL (Forced quit)

It seems that the program continued to run.

For 10M coroutines, you would need more memory, as each currently needs 256KB RAM commitment, or lower the stack settings. I wonder where is the unreachable coming from, it should normally fail with error.OutOfMemory.

My total memory is 15G, but the actual memory before the SIGABRT was about 9G.

Executed in  304.40 secs    fish           external
   usr time    0.44 secs    0.00 millis    0.44 secs
   sys time   26.99 secs    1.13 millis   26.99 secs

fish: Job 1, 'time ./zig-out/bin/zigtmp' terminated by signal SIGABRT.

Note that this is a different run.

For 10M concurrent tasks with the default stack settings, you would need 2.4TB of RAM. Even if you reduce the initial commitment to 64KB, which is fine, you would need 610GB of RAM. This is just not realistic with stackful coroutines. You can get the initial stack commitment much lower and run that many tasks, but be aware that many functions in stdlib expect fairly large stack size, multiple 64KB+ stack allocations per function are common. It will not overflow the stack, because the reservation is larger, but you will exhaust memory.

This reminds me of a general question about the new Io.Evented implementation being worked on in the std library. Will this be stackful or stackless, do you know?

As it is, it’s based on stackful coroutines, but actually allocating 60MB stacks per coroutines, so you can’t run many of them. The coroutine implementation is very similar to zio, but zio supports more platforms/cpus.