Zig's New Async I/O

I want to leave my opinion here: HN is (way) worse than Reddit when it comes to feedback.

Having a HN discussion result in something useful, is from my experience rarer than any other platform I know of where programming related topics are discussed.

1 Like

No, because it’s possible to perform I/O without allocating memory.

For the case of “comparison with prior art” there are mainly 3 well developed runtime like libraries currently in Zig (which i know of and got any traction).

  1. Tardy which is possibly the closest one to the IO interface. (io_uring, epoll, kqueue)
  2. Zig-aio (io_uting, iocp)
  3. Karlseguin has his own backed for his libraries, a lot of zig web dev is building on top of them. (kqueue, epoll)

I am a bit out of my league when it comes to designing async runtimes, so i cant judge the quality of the implementation itself. If anyone knows some well implemented ones feel free to add them / correct me.

I personally did some speed testing of tardys zzz and Karlseguins http.zig a while back. I am not confident that i set up both servers to the most optimal config, but zzz outperformed http.zig (i made both use the same backend). This might also be because the server itself is better implemented, so it might be bad representation of the runtime performance itself.

Also there was this video comparing tardys zzz to other languages high perf implementations, i am not sure how well is this benchmark made, but seems like tardy is competetive in speed and migh be a good reference point to compare to.

Robert :blush:

4 Likes

Yeah, Karl’s kqueue implementation is rock solid and at least in my limited experience… battle tested.

I’ve been using the http.zig backend in production now for over 2 years on FreeBSD without incident.

Last “let’s break it” test I did - was able to run 40k concurrent SSE connections, each updating every second, from a single worker thread on a $10/pm vps machine. No missed packets. Happy.

We had a small race condition issue with epoll recently with SSE, but that got solved within the hour.

Really want to start early doing the porting of http.zig to the new async branch, because my unique use case ideally needs to be able to handle 10,000 long lived SSE connections per server … I’m currently handling that by storing all the open streams in a hashmap and publishing to them from inside short lived response handlers.

If I can have a green thread per connection that will make the code much easier to follow. I just need to be 100% sure that the coroutine overhead is low enough to not hurt performance.

For reference - I’m also doing the DataStar zig sdk using this method to provide automatic pub/sub topics across SSE … as a hi performance alternative to the Go pattern of using goroutines + NATS

The other critical piece of my puzzle is to port backstage to the new async mechanism

This is an actor framework that whilst pretty “new” … has been working flawlessly for me

It’s backed by libxev to provide the event loop. Having a great API to capture timeout events is super important in my app, and it does that well.

So if I can get both backstage and http.zig using zig std io + the same event loop code, then that’s a big win for me.

Having a good actor framework can make some types of async/concurrent apps easy to reason about, and a joy to work on.

1 Like

A post was split to a new topic: Zig Showtime #42: AsyncIO Demo’s