Tokio: The Async Runtime
Here's something that surprises people coming to async Rust: the language gives you async/await and the
Future trait, but it does not ship anything to actually run those futures. A Future in Rust is
inert - it does nothing until something polls it to completion. That something is a runtime, and in
practice that runtime is Tokio. Every async web framework you'll meet - axum,
actix-web, Rocket - runs on it. This is the
roots guide: learn Tokio and the #[tokio::main] at the top of every Rust server stops being a magic
incantation.
The mental model is a producer and an engine. Your async fns produce futures - lazy descriptions of
work that yields at each .await. Tokio is the engine that drives them: it has a scheduler that
runs many futures concurrently across a small pool of OS threads, spawns independent work as tasks,
and wakes a future when the thing it was waiting on (a socket, a timer, a channel) is ready. Hold "futures
are inert plans; the runtime is what executes them," and async Rust clicks.
📝 This is a roots guide - it assumes you know Rust, including the basics of
async/awaitand theFuturetrait (Rust From Zero). It pairs with hyper & tower (the HTTP layer above Tokio) and underpins every Rust framework guide. Examples run as plain Rust programs (cargo run), shown with their output.
How to read this
Short and foundational - read in order. It builds from "why a runtime exists" up to spawning, scheduling,
channels, and select!. Phases carry difficulty badges.
The phases
- What Tokio Is & Why Futures Need a Runtime 🟢 - inert futures, the runtime that drives them, and
#[tokio::main]. - Async, Await & Futures 🟡 - the
Futuretrait, what.awaitdoes, and cooperative yielding. - Tasks & Spawning 🟡 -
tokio::spawn, tasks vs threads, andJoinHandle. - The Runtime & Scheduler 🔴 - the multi-threaded work-stealing scheduler, blocking the executor, and
spawn_blocking. - Channels & Synchronization 🔴 -
mpsc/oneshot/broadcast, and async-awareMutexvsstd. - select! & Timeouts 🔴 - racing futures with
tokio::select!, timeouts, and cancellation. - Where to Go Next 🟢 - how axum/actix use Tokio, and the async ecosystem.
The throughline:
async fns make inert futures; Tokio is the engine that polls, schedules, and wakes them. Every Rust web server is a pile of futures running on this runtime.