Async crate comparison

Rust's approach to bringing async code into the language is novel, in that instead of packaging the async system with the language, such as Golang's approach of providing in-built goroutines, it presents an interface to be used by independent crate developers to implement the async runtime for a given process. It also separates the job of the executor or runtime (which polls the futures) and the reactor (which tells the executor when the futures should be polled). Out of this interface, a number of projects have emerged.

Crates that provide both a runtime and IO abstractions often have their IO depend on the runtime. This can make it difficult to write runtime-agnostic code.

Futures
The crate provides common abstractions for asynchronous code. It defined the original  trait before it was moved into the standard library, and now provides many useful runtime-agnostic abstractions and tools such as asynchronous streams, sinks, locks and IO traits. It comes with a basic executor.

Gradually, most of the features that the futures crate provides will be moved into the standard library.

Tokio
is the oldest and most widely used asynchronous runtime, surpassing all other runtimes in usage combined. It provides a runtime and IO, as well as useful asynchronous utilities including process spawning, signal handling, channels, locks, and timers. It was created in 2016 by Carl Lerche, who is also the author of mio.


 * Tokio's IO is based on mio.
 * It supports several executors, configurable by user. The runtime is started manually by the user using either the  module, or with the   macro.

async-std
was originally published in August 2019 by Stjepan Glavina with the aim of developing a full runtime whose API mirrors Rust’s standard library. Like Tokio, it provides an executor, IO, and many asynchronous utilities. It provides a single global runtime, which is started on first use. Its IO and executor now use the smol executor under the hood. The original author left the project in early 2020 to work on another runtime, and Yoshua Wuyts is the current lead of the project.

The second most widely used runtime is async-std.

smol
is Stjepan Glavina’s second runtime, released in April 2020. One of its core selling points is the small size of the source code, with much of the complexity abstracted into the crate. Unlike async-std and Tokio, both of which provide their own implementations of asynchronous utilities nearly identical to the standard library's, smol provides a single type:, which can wrap around nearly any standard library IO type to make it asynchronous. It comes with an executor and timer utilities, but lacks features such as locks, channels and process spawning, which Tokio and async-std have.

It provides global and per-thread runtimes without customization that are started on first use. It uses epoll for IO on Linux, kqueue on macOS/iOS/*BSD and the wepoll library on Windows (which emulates the behaviour of epoll).

Actix
is an actor system created in 2017 with a focus on a type-safe actor model and extensibility. It forms the basis of the back-end web framework actix-web. Actix uses Tokio under the hood.

embrio
A runtime intended for embedded systems, developed by Wim Looman since 2018.

Bastion
pivots towards supervision and fault tolerance in the spirit of Erlang. Conceived in July 2019 by Mahmut Bulut.

Mio
is a crate for low-level cross-platform non-blocking IO. In the standard library, all IO is called synchronously and blocks the thread it is called from — this means that only one IO task can be performed at once per thread. Mio provides an API to specify the IO tasks to wait for and a way to block until the first one has finished, allowing a large number of IO tasks to run at once. It is used for the underlying implementation of many IO reactors including Tokio. async-std also used it before it switched to smol.

Low Level Crates (io_uring based)
io_uring is a new completion based asynchronous IO API for Linux. It is still new and support in Rust is highly experimental, but it promises better throughput than traditional Linux async-io approaches such as epoll, especially for filesystem IO.

Rio
is a crate for low-level crate targeting io_uring

Ringbahn
targets a safe API for io_uring.

rotor
The oldest asynchronous runtime ever developed for Rust which included its own vision of  trait. Eventually deprecated by the currently dominant Tokio stack.