Tokio Knowledge Patch
Baseline: Tokio through 1.39.x. Covered range: Tokio 1.39.0 through 1.52.0, plus the included tokio-util and tokio-stream updates.
Use this patch to choose safe dependency floors, account for changed behavior, and select APIs added after the baseline. Check the detailed topic reference before implementing version-sensitive code.
Reference index
| Reference | Topics |
| --- | --- |
| compatibility.md | Rust and dependency floors, safe patch releases, upgrade regressions, build flags |
| runtime-and-tasks.md | Runtime construction, local execution, cooperative scheduling, task APIs, metrics, tracing |
| synchronization.md | watch, broadcast, mpsc, oneshot, Notify, permits, and single-assignment state |
| io-and-filesystem.md | Async I/O types, files, pipes, AIO, and unstable io_uring filesystem support |
| networking-process-signals.md | Socket behavior and options, platform targets, child processes, and signals |
| tokio-util-and-stream.md | tokio-util 0.7.12–0.7.18 and tokio-stream 0.1.16–0.1.18 |
Breaking changes and upgrade gates
Select safe patch releases
- Avoid Tokio 1.39.0: it is yanked. Use 1.39.3 on the 1.39 line to include the timer-wheel rollback, temporary-lifetime
select!restoration, and Unix abstract-address restoration. - Use at least 1.42.1 when a
broadcastchannel may carry aSendbut non-Syncvalue; 1.42.0 has an unsynchronized-clone soundness bug. - Use 1.43.4 on the 1.43 line for the pidfd, receiverless
broadcast, and closed-and-drainedmpsc::try_recvfixes. - Use at least 1.45.1 on
wasm32-unknown-unknown; 1.45.0 can panic while collecting time-based metrics. - Use at least 1.46.1 when task hooks consume
TaskMeta::spawned_atfor tasks created withtokio::spawn. - Use 1.51.3 on the 1.51 line for the accumulated channel and
RwLockfixes, and at least 1.51.1 for Linux UDP error reporting and the cancelled io_uring-open descriptor fix. - Use at least 1.52.1; 1.52.0's sharded
spawn_blockingqueue can hang.
See compatibility.md for the complete patch-level behavior list.
Enforce compiler and dependency floors
| Package floor | Requirement |
| --- | --- |
| Tokio 1.39.0 | Rust 1.70 or newer |
| Tokio 1.48.0 | Rust 1.71 or newer |
| tokio-util 0.7.12 | Rust 1.70 or newer |
| tokio-util 0.7.17 | Rust 1.71 or newer |
| tokio-util 0.7.18 | Tokio 1.44.0 or newer |
| tokio-stream 0.1.16 | Rust 1.70 or newer |
Adjust changed or rejected code
- Put standard-library sockets into nonblocking mode before any Tokio
from_stdconversion. Since 1.44.0, passing a blocking socket panics.
let listener = std::net::TcpListener::bind(addr)?;
listener.set_nonblocking(true)?;
let listener = tokio::net::TcpListener::from_std(listener)?;
- Keep
runtime::Builder::event_intervalnonzero; passing0panics since 1.50.0. - Do not call Tokio's in-place blocking operation while polling or dropping a
LocalSetas of 1.46.0. Move blocking work tospawn_blockingor outside the local set. - Replace deprecated
TcpStream::set_lingerandTcpSocket::set_lingercalls. For an abortive close, useTcpStream::set_zero_linger()from 1.50.0. - Consume or explicitly discard the results of
JoinHandle::abort_handle()andNotify::notified(); their types became#[must_use]in 1.40.0 and 1.41.0. - Stop treating signal-stream
Noneas a shutdown path. Since 1.50.0, signal listeners are guaranteed to remain open; use explicit cancellation. - Expect a task future's retained state to be dropped before its
JoinHandlecompletes as of 1.50.0. - Account for changed diagnostics: formatting a panicked task's
JoinErrorincludes the panic message since 1.40.0.
Update unstable configuration
- Enable
taskdumpandio_uringas Cargo features as of 1.48.0; do not use the former custom--cfgswitches. - Pass
LocalOptionsby value to unstableBuilder::build_localas of 1.46.0. - Migrate away from the removed unstable alternate multi-threaded runtime as of 1.45.0.
- Treat io_uring as opportunistic: Tokio can disable it after
EPERMand checks kernel opcode support before dispatch.
Runtime and task quick reference
Choose local execution deliberately
- Use stable
tokio::runtime::LocalRuntimefrom 1.51.0 for thread-local!Sendtasks. It first appeared as an unstable API in 1.41.0. - With unstable APIs on 1.48.0,
#[tokio::main(flavor = "local")]and the corresponding test macro provide a local-runtime macro entry point. - Use stable
runtime::id::IdandLocalSet::id()from 1.49.0 to identify runtimes and local sets. - From 1.51.0, assign runtime names and call
tokio::runtime::worker_index()for diagnostic context.
Preserve cooperative scheduling
watchreceives andbroadcast::Receiverbecame cooperative in 1.41.0.select!became budget-aware in 1.44.0.- Use
tokio::task::coopfor custom resources from 1.44.0;cooperativeandpoll_proceedare available from 1.47.0. yield_nowtakes effect immediately insideblock_in_placeas of 1.42.0.- Use
biased;withjoin!ortry_join!from 1.46.0 only when declaration-order polling is intentional.
let (first, second) = tokio::join!(biased; first_job(), second_job());
Use newer task primitives
- Use
tokio::sync::SetOncefrom 1.47.0 for single assignment. - Use
Notify::notified_owned()andOwnedNotifiedfrom 1.47.0 when the notification future must not borrow itsNotify. - Extend a
JoinSet<T>from an iterator withExtendas of 1.49.0. - Sort
task::Idvalues or use them as ordered keys as of 1.48.0. - Use
LocalKey::try_get()from 1.48.0 when absent task-local state should not panic.
Read metrics with their guarantees
- Stable per-worker busy duration and park/unpark counts arrive in 1.45.0.
- Unstable spawned-task totals, combined worker park/unpark counts, and worker thread IDs arrive in 1.39.0.
- Unstable H2 histogram configuration and renamed histogram APIs arrive in 1.41.0.
- Do not use
num_alive_tasksas an exact concurrent invariant; its samples are not strongly consistent as of 1.49.0.
Read runtime-and-tasks.md for lifecycle hooks, poll callbacks, task dumps, spawn locations, and eager driver handoff.
Synchronization quick reference
- Await
broadcast::Sender::closed()from 1.44.0 to stop producers after all receivers disappear. - Hold a
broadcast::WeakSenderfrom 1.44.0 when an observer must not keep a channel open. - Inspect
oneshot::Receiversynchronously withis_empty()andis_terminated()from 1.44.0. - Compare an
mpsc::OwnedPermitwith another permit or sender usingsame_channelandsame_channel_as_senderfrom 1.46.0. - Derive
Defaultfor structures containingwatch::Sender<T>whenT: Defaultas of 1.39.0. - Use Tokio mpsc types across unwind-safety bounds as of 1.40.0.
Read synchronization.md before depending on close, permit, wakeup, or fairness semantics.
I/O, networking, process, and signal quick reference
I/O and files
- Use
util::SimplexStreamfrom 1.40.0, ortokio_util::io::simplexfromtokio-util0.7.18. - Name the concrete chained-reader type with public
tokio::io::Chainfrom 1.48.0. - Read a file's configured buffer limit with
File::max_buf_size()from 1.48.0; clones now preserve that limit. - Use
unix::pipe::{Sender, Receiver}::try_iofrom 1.52.0 for custom nonblocking endpoint operations. - Use
AioSource::register_borrowedfrom 1.52.0 to register a borrowed resource without transferring ownership.
Networking
- Use Unix
SocketAddrstandard-library conversions from 1.41.0, cloning from 1.46.0, andas_abstract_name()from 1.48.0. - Use
TcpStream::{quickack,set_quickack}from 1.48.0 where the platform exposes TCP quick acknowledgements. - Configure IPv6
TCLASSthrough Tokio from 1.49.0. - Require 1.46.0 when successful macOS
TcpStream::shutdownbehavior matters.
Processes and signals
- Configure Unix child process groups with stable
Command::process_groupfrom 1.40.0. - Use
Command::spawn_withfrom 1.45.0; its callback may beFnOncefrom 1.48.0. - Treat
Child::start_kill()after normal exit as a successful cleanup race from 1.44.0. - Account for illumos realtime signals from 1.43.0 and Windows console close, logoff, and shutdown events from 1.44.0.
Read io-and-filesystem.md and networking-process-signals.md for backend and target details.
Companion crate quick reference
tokio-util
- Compose cancellation with
run_until_cancelled, its owned form, orFutureExtadapters; cancellation wins a simultaneous-ready tie from 0.7.16. - Use
AbortOnDropHandlefrom 0.7.12 and detach it from 0.7.16. - Use stable
JoinMapfrom 0.7.16 andJoinQueuefrom 0.7.17. - Recheck framing capacity assumptions: from 0.7.16,
Framed::with_capacityapplies the capacity to the read buffer too.
tokio-stream
- Batch
StreamMapresults withnext_manyorpoll_next_manyfrom 0.1.16. - Name public stream adapter types from 0.1.16.
- Recover an incomplete timed chunk with
ChunksTimeout::into_remainderfrom 0.1.18. - Use meaningful receiver-stream
size_hintbounds from 0.1.18.
Read tokio-util-and-stream.md for all included companion-crate changes and exact release floors.