Tokio
Tokio
Tokio is the runtime behind async Rust in Rust. The part worth remembering is not "async equals fast." The real split is:
tokio::join!gives concurrency inside one parent task — see Concurrent Is Not Paralleltokio::spawngives the runtime an independent task it can schedule across worker threadstokio::task::spawn_blockingkeeps synchronous or CPU-heavy work off the async worker pool
This page is the hub. The load-bearing rules each have their own atomic note.
Rules I want to keep
- Size throughput by worker threads. Do not treat
#[tokio::main]as a bonus worker for parallelism math. - Classify the work first — async I/O, short CPU, bounded blocking, long-lived blocking, or heavy CPU parallelism. See Classify Async Work Before Refactoring.
- Concurrent is not parallel. Use
join!for a small fixed set of async I/O operations; usespawnwhen work should become its own task and may benefit from multi-thread scheduling. See Concurrent Is Not Parallel. - Bound the fan-out. Default to
JoinSetplus aSemaphore, not unbounded spawn storms. See Bounded Concurrency First. - Protect the hot path from the warm path. Background work should have its own bounds, freshness rules, and downstream isolation. See Hot Path vs Warm Path and Priority Lanes Need Downstream Isolation.
- Never hold a mutex guard across
.await. See Don't Hold a Lock Across Await. - Prefer
std::sync::Mutexorparking_lot::Mutexfor short sync critical sections. - Use
tokio::sync::Mutexonly when the guarded operation truly has to cross.await. - Use
spawn_blockingfor bounded sync or CPU-heavy work. - Use a dedicated
std::thread::spawnworker for long-lived blocking loops.
What this means for mxr
Good places to parallelize:
- per-account sync work
- attachment extraction
- semantic prep work that does not immediately fight over the same lock
- expensive local decode or rendering steps
Bad places to parallelize:
- tiny operations where spawn overhead dominates
- paths that still serialize on one lock or one writer
- anything that holds
search,semantic, or similar shared state longer than necessary
Pointer
Repo reference guide: docs/reference/tokio-runtime-guide.md