Under The Hood
backend rust Tokio 1.x

Tokio runtime: work stealing and task scheduling

Last updated
Prerequisites:
Rust async/await basics
Familiarity with Tokio's multi-threaded runtime
tokio::main macro usage
  • rust
  • tokio
  • async
  • runtime
  • work-stealing
  • scheduler

Read at your depth

The practical view

#[tokio::main] async fn main() starts a Tokio runtime. The multi-threaded runtime (default with the rt-multi-thread feature) spawns one worker thread per core, each with its own task queue, and work-stealing balances load. spawn(async { ... }) schedules a task; await points yield control back to the runtime; timers (tokio::time) and I/O (tokio::net, tokio::fs) integrate with the reactor. The single-threaded runtime (flavor = "current_thread") is the lightweight option for CPU-bound or simple I/O programs. Tasks are Send because the runtime may move them across worker threads — that is why spawned futures must be Send + 'static.

Legacy vs modern

Blocking a worker thread vs proper async spawn

Synchronous blocking inside async code stalls the whole worker; delegating the blocking call to spawn_blocking keeps the scheduler responsive.

before → after
Blocking inside async
async fn handle() {
  std::thread::sleep(Duration::from_millis(500)); // blocks the worker
  process(&data);
}
spawn_blocking delegation
let data = tokio::task::spawn_blocking(|| fs::read("big.bin")).await??;

Interview gotchas

Under The Hood — a multi-depth technical interview hub.

Press ⌘ K to search.