This is my project.
I use it as the core cross-platform event loop layer for my terminal (https://mitchellh.com/ghostty). I still consider libxev an early, unstable project but the terminal has been in use by hundreds to now over a thousand beta testers daily for over a year now so at least for that use case its very stable. :) I know of others using it in production shipped software, but use it at your own risk.
As background, my terminal previously used libuv (the Node.js core event loop library), and I think libuv is a great project! I still have those Zig bindings available (archived) if anyone is interested: https://github.com/mitchellh/zig-libuv
The main issue I had personally with libuv was that I was noticing performance jitter due to heap allocations. libxev's main design goal was to be allocation-free, and it is. The caller is responsible for allocating all the memory libxev needs (however it decides to do that!) and passing it to libxev. There were some additional things I wanted: more direct access to mach ports on macOS, io_uring on Linux (although I think libuv can use io_uring now), etc. But more carefully controlling memory allocation was the big one.
And it worked! Under heavy IO load in my terminal project, p90 performance roughly matched libuv but my p99 performance was much, much better. Like, 10x or more better. I don't have those numbers in front of me anymore to back that up and my terminal project hasn't built with libuv in a very long time. But I consider the project a success for my use case.
You're probably better off using libuv (i.e. the Node loop, not my project) for your own project. But, the main takeaway I'd give people is: don't be afraid to reimplement this kind of stuff for you. A purpose-built event loop isn't that complicated, and if your software isn't even cross-platform, it's really not complicated.
Thank for you for sharing.
What do you think are the next steps for a next generation event loop?
I've been experimenting with barriers/phasers, LMAX Disruptors and my own lock free algorithms.
I think some form of multithreaded structured concurrency with coroutines and io_uring.
I've been experimenting with decoupling the making sending and recv independently parallel with multiple io_urings "split parallel io" - so you can process incoming traffic separately from the stream that generates data to send. Generating sends is unblocked by receive parsing and vice versa.
Interested in seastar and reactors.
https://en.wikipedia.org/wiki/Data_Plane_Development_Kit
Is dpdk still needed after io_uring? io_uring can also do zero-copy packet processing
edit: there is this thesis https://liu.diva-portal.org/smash/get/diva2:1789103/FULLTEXT...
On 5.1.5 Summary of Benchmarking Results (page 44)
Ok 25Gbps vs 5Gbps seems like a huge difference, specially since io_uring was having higher packet loss as well
Thank you for that. Would be interesting to see benchmarks.
Maybe "allocation-free" should be in the GitHub project description instead of or in addition to "high performance".
It is
To be clear, I am discussing the text under "About" in the top right, labeled as "Description" when edited, which currently states:
... with no mention of zero-allocation though yes it is mentioned later as a feature in the README.
Very nice! TBH, libuv sometimes felt like it is popular because it's popular rather than sheer technical prowess. I was never comfortable with how much allocation is done by it, and I don't always find how it deals with platform primitives as useful as I'd like.
Amen. There's no need to view the event loop as mysterious. It's just a while loop that is constantly coordinating IO.
Three, I wanted an event loop library that could build to WebAssembly (both WASI and freestanding) and that didn't really fit well into the goals of API style of existing libraries without bringing in something super heavy like Emscripten.
This is a cool motivation!
Could you drop this into Node to make Nodeex ? A kind of experimental allocation-free Node that somehow carves out the allocations into another layer (admittedly still within the node c code)?
I saw ghostty and thought, “isn’t that the terminal written by the guy who cofounded hashicorp?”. I really enjoy your ghostty blog posts and will be checking out libxev!
(Off topic) but any chance you might include me in the ghostty private testers? (adonese@nil.sd)