tokio
Tokio is the de facto async runtime for Rust network services. It provides an executor, timers, async IO, and synchronization primitives built for async/await.
Search across all documentation pages
Tokio is the de facto async runtime for Rust network services. It provides an executor, timers, async IO, and synchronization primitives built for async/await.
[dependencies]
tokio = { version = "1", features = ["full"] }#[tokio::main]
async fn main() {
let handle = tokio::spawn(async {
tokio::time::sleep(std::time::Duration::from_millis(10)).await;
42
});
let n = handle.await.unwrap();
assert_eq!(n, 42);
}When to reach for this:
axum, hyper)sqlx)use tokio::net::TcpListener;
use tokio::io::{AsyncReadExt, AsyncWriteExt};
#[tokio::main]
async fn main() -> std::io::Result<()> {
let listener = TcpListener::bind("127.0.0.1:0").await?;
let addr = listener.local_addr()?;
tokio::spawn(async move {
let (mut socket, _) = listener.accept().await.unwrap();
let mut buf = [0u8; 4];
socket.read_exact(&mut buf).await.unwrap();
socket.write_all(b"pong").await.unwrap();
});
let mut client = tokio::net::TcpStream::connect(addr).await?;
client.write_all(b"ping").await?;
let mut out = [0u8; 4];
client.read_exact(&mut out).await?;
assert_eq!(&out, b"pong");
Ok(())
}What this demonstrates:
#[tokio::main] sets up the multi-thread runtimespawn runs concurrent tasks| Feature set | Use |
|---|---|
rt-multi-thread | Production servers (default in full) |
rt | Single-threaded embedded or tests |
macros | #[tokio::main], #[tokio::test] |
time | sleep, interval, timeouts |
See the Tokio basics section for channels, select!, graceful shutdown, and tracing integration.
std::fs::read blocks the worker thread. Fix: tokio::task::spawn_blocking or tokio::fs.rayon.current_thread runtime surprises - tasks only run when polled on one thread. Fix: use multi-thread for servers.enable_io - custom runtime builder without IO feature fails at accept. Fix: mirror full features explicitly.| Alternative | Use When | Don't Use When |
|---|---|---|
async-std | Legacy codebases | Greenfield Tokio ecosystem crates |
smol | Lightweight runtime | Heavy Axum/sqlx stacks |
| Sync threads | CLI batch tools | Thousands of concurrent connections |
Yes. Minor 1.x releases are semver-compatible. Pin 1 in Cargo.toml.
Default is CPU cores. Tune with worker_threads(n) on RuntimeBuilder for mixed workloads.
Yes at boundaries: spawn blocking for sync libraries; keep async at the network edge.
No. Use threads for CPU parallelism; Tokio for concurrent IO waiting.
Stack versions: This page was written for Rust 1.97.0 (edition 2024), Tokio 1.x, Axum 0.8, serde 1.0, sqlx 0.8, clap 4, and Polars 0.46+.
Reviewed by Chris St. John·Last updated Jul 19, 2026