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, some of the features that the futures crate provides will be moved into the standard library.

Becase is slow to compile, some developers are maintaining subsets of it called and.

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 Aaron Turon, Alex Crichton, and Carl Lerche (who is the author of and the primary maintainer of Tokio today).


 * Tokio's I/O 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.
 * Tokio uses custom IO traits like   /  , requiring a compatibility layer to integrate with.

is the first stable async runtime and the first to adopt the async/await syntax. It was published in August 2019 by Yoshua Wuyts and Stjepan Glavina with the aim of developing a full runtime whose API mirrors Rust’s standard library. It provides an executor, async IO, and many asynchronous utilities.


 * Its IO and executor use and under the hood.


 * There is a single global runtime, which is started on first use.
 * async-std uses I/O traits from the crate.

is Stjepan Glavina’s second runtime, released in April 2020. Its core selling points are small size and fast compilation. Much of the complexity is abstracted into individual crates like, , and. Unlike async-std and Tokio, which provide their own async networking types, smol provides a single type:, which can wrap any standard networking type to make it asynchronous.


 * Its IO and executor use and under the hood.


 * An executor is started by.
 * Smol uses I/O traits from the crate.

Other utilies live in, , , , , and.

Smol is more a collection of independent async crates rather than a single runtime itself. This collection makes it easy to build new runtimes. A lot of them have now been adopted by async-std.

Actix
is an actor system created in 2017 with a focus on a type-safe actor model and extensibility. Actix uses Tokio under the hood.

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.

Comparison of Async Ecosystems
There are three main async ecosystems in use:
 * , which is the oldest one. It is one large crate made lighter with feature flags.
 * , which is newer. It changed to use Smol's executor once Smol was released. It is also one large crate.
 * , which is the newest and is split up into many many different crates. Lots of the crates listed in this column have types reexported by the smol crate, but some are completely independent.

Additionally, this table lists, which isn't an ecosystem like Tokio or async-std but contains many useful future-related types.

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.

polling
offers a portable interface to epoll/kqueue/wepoll. It was created as a simpler alternative to and is used by, which is the basis for async I/O in   and. Supported platforms are Linux, Android, macOS, iOS, FreeBSD, NetBSD, OpenBSD, DragonFly BSD, illumos, Solaris, and Windows. Events are triggered in the 'oneshot' fashion.

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 I/O approaches such as, especially for filesystem IO.

is a safe and convenient API for using  from Rust idiomatically.

is another low-level crate targeting, however, usage of it is highly discouraged due to an explicit case of unsoundness (UB accessible from safe code) which the author decided not to fix at all.

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