futures-timer
Heap-based async timers, delays, and timeouts for Rust futures.
Repository Health
Technical Analysis
futures-timer is a small, general-purpose Rust crate that brings timeouts and delays to the async ecosystem. Its centerpiece is the Delay future, which resolves after a given Duration, letting you sleep, debounce, or time out any future without pulling in a full async runtime.
Under the hood it drives a single global timer thread backed by a binary heap, so thousands of concurrent delays share one OS timer rather than one thread each. The same API compiles to WebAssembly via the wasm-bindgen feature, making it a portable timing primitive for async-std, Tokio, smol, and browser targets alike.
What You Get
- A
Delayfuture that completes after a configurableDuration - A shared, heap-based global timer thread that scales to many concurrent timers
- First-class WebAssembly support through the optional
wasm-bindgenfeature - A resettable timer handle for building debounce and timeout combinators
- Runtime independence — works with async-std, Tokio, smol, and others
Common Use Cases
- Sleeping or delaying inside async code without blocking a thread
- Adding timeouts to network requests or other futures that may hang
- Implementing debounce, throttle, and retry-with-backoff logic
- Scheduling periodic async work on WebAssembly and native targets
Under The Hood
Architecture — The public surface in src/lib.rs is a single re-export of Delay, selected at compile time between the native implementation (src/native/) and a wasm-bindgen variant (src/wasm.rs). The native path is where the design lives: heap.rs and heap_timer.rs implement a binary-heap of scheduled deadlines, timer.rs and global.rs run one shared background timer thread that all Delay instances register with through a TimerHandle, and arc_list.rs plus atomic_waker.rs provide the lock-light intrusive list and waker cell used to notify futures when their deadline elapses.
Tech Stack — Pure Rust (edition 2018) with no runtime dependencies on native targets; the only optional dependencies are gloo-timers and send_wrapper, pulled in behind the wasm-bindgen feature for browser builds. It integrates with the wider futures ecosystem and is tested against async-std.
Code Quality — The crate enforces #![deny(missing_docs)] and warns on missing Debug impls, so the API is fully documented. Integration tests in tests/smoke.rs and tests/timeout.rs exercise the timing behavior, and the handful of unsafe blocks needed for the heap and waker are explicitly called out and justified in the README’s safety section.
API Design — Ergonomics are the standout: Delay::new(Duration::from_secs(3)).await is all it takes, with no runtime handle, context, or registration boilerplate. The same call site compiles unchanged for native and WASM, and the resettable timer handle composes cleanly into debounce and timeout combinators.