thread_local

Per-object thread-local storage for Rust, beyond the standard library's static thread_local! macro.

Library
Cargo
v1.1.10
372stars
MIT OR Apache-2.0

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
62/100Good
Development Activity56
Maintenance48
Community64
Maturity60
Momentum20

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
78/100Good
Architecture80
Code Quality82
Innovation70
Learning Curve78

thread_local is a Rust crate providing the ThreadLocal type, which lets a single object own a separate copy of a value per thread, without those copies needing to be declared as static the way the standard library’s thread_local! macro requires. This makes it possible to attach thread-local state to a heap-allocated, dynamically-created object — for example, a connection pool, a buffer cache, or a per-thread accumulator tied to one struct instance rather than a global.

Written and maintained by Amanieu d’Antras (also known for hashbrown and parking_lot), thread_local is a foundational low-level concurrency primitive used throughout the Rust ecosystem wherever per-thread scratch storage needs to be scoped to an object’s lifetime rather than the whole program.

What You Get

  • The core ThreadLocal<T> type: per-object, per-thread storage created lazily on first access from each thread
  • A CachedThreadLocal/cached access path (cached.rs) for faster repeated access from the same thread
  • An iterator over all per-thread values currently stored, useful for aggregating per-thread state (e.g. summing per-thread counters)
  • An optional nightly feature flag enabling performance improvements on nightly Rust toolchains
  • A minimum supported Rust version (MSRV) of 1.63, keeping it usable in reasonably conservative toolchains

Common Use Cases

  • Giving each worker thread its own scratch buffer or accumulator tied to one long-lived object instance
  • Building per-thread caches or connection pools that need aggregation across all threads that touched them
  • Implementing lock-free-ish patterns where each thread mutates only its own copy, merged later via the iterator API
  • Replacing ad-hoc Mutex<HashMap<ThreadId, T>> patterns with a purpose-built, more efficient per-object thread-local type

Under The Hood

Architecture: The crate centers on a thread_id.rs module that allocates small, reusable, densely-packed thread IDs (rather than relying on the OS’s native, often large or non-reusable IDs), and a core ThreadLocal<T> in lib.rs that stores per-thread slots in an internal table indexed by that thread ID, growing the table as new threads first access it; cached.rs layers a faster-path cache on top of that same table for repeat access from an already-registered thread. Tech Stack: A minimal-dependency, pure Rust crate depending only on cfg-if for conditionally gating nightly-only code paths, with no allocator or runtime dependencies beyond std. Code Quality: src/lib.rs includes an embedded mod tests covering core behavior, complemented by a benches/ directory for performance regression tracking, reflecting the crate’s role as a widely-depended-upon low-level primitive where correctness and performance regressions both matter. API Design: The public surface is intentionally small — construct a ThreadLocal::new(), call .get_or()/.get_or_default() per thread, and iterate with .iter_mut() to aggregate — mirroring the ergonomics of the standard library’s own thread_local! macro closely enough that existing Rust developers need almost no new mental model.

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers

Search