Library / SDK
Amanieu/parking_lot avatar
Amanieu/parking_lot

parking_lot: smaller, faster Rust synchronization primitives

Compact and efficient synchronization primitives for Rust. Also provides an API for creating custom synchronization primitives.

3,417 stars283 forksRustApache-2.0

At a glance

What is it?
The parking_lot crate replaces std::sync::Mutex, RwLock, Condvar and Once with versions that need less storage and offer extra capabilities. Here is how the parking lot mechanism works, how to install it, and when it is the wrong choice.
Who is it for?
Adopt parking_lot when you need small lock footprints, recursive locking, lock downgrades or guard sending, and you accept that the minimum Rust version is 1.84 and may change at any time. Do not adopt it if you rely on std::sync::Condvar or Once serde support, or if you build for wasm32-unknown-unknown on stable with atomics enabled, since the README states that combination breaks the concurrency guarantees.
Can I use it commercially?
Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 34 days ago.
What is it written in?
Mainly Rust, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 30, 2026, and from our analysis. They are not legal advice.

Editorial analysis

What parking_lot replaces and who it is for

parking_lot is a Rust crate that provides implementations of Mutex, RwLock, Condvar and Once that the README describes as smaller, faster and more flexible than those in the Rust standard library. It also ships a ReentrantMutex type for recursive locking and exposes a low-level API for building custom synchronization primitives.

The audience is Rust systems programmers who care about the cost of synchronization. The README gives the storage sizes directly: Mutex and Once need 1 byte, while Condvar and RwLock need 1 word. On some platforms, including macOS, the standard library primitives need a dynamically allocated Box to hold OS-specific synchronization state. That difference matters when locks live inside structs that get allocated in large numbers, because a smaller Mutex makes fine-grained locking cheaper to afford.

The library is not a rewrite of the standard library's semantics. It is a drop-in style replacement for the common types, with extra methods on top. The README's own performance note says that on x86_64 Linux, parking_lot::Mutex was 1.5x faster than std::sync::Mutex uncontended and up to 5x faster under contention, and that RwLock is almost always faster, up to 50x in some cases. Those are the project's figures, not an independent benchmark.

The parking lot: how sleeping threads are queued

The design keeps each primitive small by moving thread queuing and suspension out of the lock itself and into a shared parking lot. The README credits the idea to Webkit's WTF::ParkingLot, which it describes as a hash table mapping lock addresses to queues of parked (sleeping) threads. Webkit's version was in turn inspired by Linux futexes, but the README notes it is more powerful because callbacks can run while a queue lock is held.

That split explains the crate layout at the top level of the repository: src/ holds the synchronization primitives, core/ holds parking_lot_core, and lock_api/ holds the type-safe lock API. The README states the core parking lot API lives in the parking_lot_core crate, separate from the primitives, so that changes to the core API do not cause breaking changes for users of parking_lot. The Cargo.toml confirms the dependency edges: parking_lot depends on parking_lot_core 0.9.12 and lock_api 0.4.14 by path.

On the fast path, the README says uncontended acquisition and release use inline paths requiring a single atomic operation. When a lock is contended briefly, the implementation spins a few times before suspending the thread, which the README calls adaptive: short and long critical sections are both handled. Eventual fairness is claimed for Mutex and RwLock, meaning they are fair on average without giving up performance. RwLock uses a task-fair policy that the README says avoids reader and writer starvation, a guarantee the standard library version does not make.

Installing parking_lot and taking a first lock

The README's usage section says to add the crate to Cargo.toml. The current published line is 0.12, matching the Cargo.toml version 0.12.5 in the repository.

toml
[dependencies]
parking_lot = "0.12"

Nightly-only functionality is behind a feature, so the README shows this alternative entry instead.

toml
[dependencies]
parking_lot = { version = "0.12", features = ["nightly"] }

Once the dependency is in place, the types are used the way a Rust programmer expects: wrap shared data in a Mutex and lock it. The Cargo.toml lists the optional features you can turn on: arc_lock, owning_ref, nightly, deadlock_detection, serde, send_guard and hardware-lock-elision. Note the README's warning that deadlock_detection and send_guard are incompatible and cannot be used together.

The minimum supported Rust version is stated as 1.84, with the caveat that it may change at any time. If you enable hardware-lock-elision, the README says that feature requires Rust 1.59 because it uses inline assembly, which is below the current floor anyway. Before adding the crate, check your toolchain against 1.84; that is the one hard environmental requirement the material states.

Extras the standard library does not offer

Several capabilities in the README are absent from std::sync. RwLock supports atomically downgrading a write lock into a read lock, and it supports upgrading an upgradable read lock into a write lock. Mutex and RwLock allow raw unlocking without an RAII guard, and Mutex<()> and RwLock<()> allow raw locking without a guard, which is useful when the lock protects external state rather than a Rust value.

Condvar behaviour is specified more tightly than the standard library's. The README says parking_lot's Condvar is guaranteed not to produce spurious wakeups: a thread wakes only on timeout or notification. It also says notify_all wakes a single thread and requeues the rest onto the associated Mutex, avoiding a thundering herd. That requeueing design is a real semantic difference, not just an optimization.

Two features change what you can do with guards. With send_guard, lock guards can be sent to other threads. With serde, Mutex, ReentrantMutex and RwLock can be serialized, though the README explicitly notes Condvar and Once are not supported by that feature. The deadlock detector for Mutex, RwLock and ReentrantMutex is marked experimental and is off by default; it is enabled with the deadlock_detection feature.

Nightly, stable and the wasm32-unknown-unknown trap

Most users can stay on stable, but there is one configuration where the README is unusually blunt. On wasm32-unknown-unknown, full support requires nightly with -C target-feature=+atomics in RUSTFLAGS and -Zbuild-std=panic_abort,std passed to cargo. On stable, the README says parking_lot works mostly fine, with the difference that it will panic instead of blocking forever if you hit a deadlock.

The warning that follows is the important part: do not enable -C target-feature=+atomics on stable, because that lets wasm run with multiple threads, which the README says will completely break parking_lot's concurrency guarantees. This is a case where a build flag that looks like a performance win silently removes the soundness the crate depends on. If you target wasm and need real threading, the nightly path is the documented one.

The stable-versus-nightly split is also why the nightly feature exists as a Cargo feature rather than being assumed. It forwards to parking_lot_core/nightly and lock_api/nightly, so the choice propagates through the workspace rather than being decided in one place.

Where parking_lot is the wrong tool

The crate is a synchronization library, not a concurrency framework. It gives you Mutex, RwLock, Condvar, Once and ReentrantMutex. It does not give you channels, thread pools, async runtimes or lock-free data structures, and the README makes no claim in those directions. If your problem is coordinating tasks rather than guarding memory, this is the wrong layer.

The deadlock detector is explicitly experimental. If your workflow depends on reliable deadlock diagnosis, the README does not present this as production tooling, and it cannot be combined with send_guard. The serde support is partial in a way that can surprise you: it covers Mutex, ReentrantMutex and RwLock only, so a type containing a Condvar or Once cannot be serialized through this feature.

There is also a portability caveat in the other direction. The README says Condvar, RwLock and Once work on Windows XP, unlike the standard library versions of those types. That is a reason to pick parking_lot for old Windows targets, but it says nothing about the reverse case of newer platforms where the standard library is already sufficient. If your locks are never contended and your structs are few, the storage savings and the faster paths may not be worth an extra dependency with its own minimum Rust version.

Alternatives and how they differ

The obvious alternative is std::sync itself. The difference is not only speed. The standard library's Mutex and Once are larger on platforms where OS primitives are boxed, its Condvar may wake spuriously, and its RwLock makes no fairness guarantee. parking_lot trades those properties for a parking lot that queues sleeping threads by lock address, plus opt-in features such as downgrade and upgrade of RwLock, raw unlock, ReentrantMutex, guard sending and the experimental deadlock detector. Choosing std::sync means fewer dependencies and no minimum-version constraint beyond the compiler you already use; choosing parking_lot means accepting the 1.84 floor and the feature interactions documented in the README.

Within the same project, parking_lot_core is a separate option. If you are building your own primitive, the README points to the core parking lot API and its own documentation, and explains that the split exists so core changes do not break parking_lot users. That is a different job from swapping out Mutex, and it comes with the responsibility of implementing the primitive correctly on top of the parking lot.

Maintenance, licensing and upgrade cost

The repository is not archived, and its last push was on 2026-08-28, which is recent. The most recent releases listed are parking_lot 0.12.5, parking_lot_core 0.9.12 and lock_api 0.4.14, all dated 2025-10-03. The presence of release-plz.toml and a CHANGELOG.md in the repository root suggests releases are automated and recorded, though the README does not describe a support policy or a deprecation process.

Upgrade cost is dominated by the minimum Rust version. The README states the current minimum is 1.84 but that it may change at any time, so a toolchain pinned below that floor is a real blocker rather than a warning. Feature flags also carry cost: deadlock_detection and send_guard cannot be enabled together, and the nightly feature pulls in nightly-only code paths across both parking_lot_core and lock_api.

On licensing, the Cargo.toml declares MIT OR Apache-2.0, and the repository carries LICENSE-MIT and LICENSE-APACHE at the top level. The README says the crate is licensed under either at your option, and that contributions are dual licensed the same way unless stated otherwise. That is the standard permissive Rust arrangement. It is not legal advice; if your organization has rules about dual-licensed dependencies, check them against the two files in the repository.

Editorial conclusion

Adopt parking_lot when you need small lock footprints, recursive locking, lock downgrades or guard sending, and you accept that the minimum Rust version is 1.84 and may change at any time. Do not adopt it if you rely on std::sync::Condvar or Once serde support, or if you build for wasm32-unknown-unknown on stable with atomics enabled, since the README states that combination breaks the concurrency guarantees. Verify first that your toolchain meets the stated minimum and that the feature flags you need (deadlock_detection and send_guard are mutually exclusive) are compatible.

Frequently asked questions

What is the parking_lot crate in Rust?

It is a library providing Mutex, RwLock, Condvar and Once implementations that the README describes as smaller, faster and more flexible than the standard library versions, plus a ReentrantMutex and a low-level API for custom synchronization primitives.

How do I install parking_lot in a Cargo project?

Add parking_lot to the dependencies section of Cargo.toml, using version 0.12 as the README shows. For nightly-only functionality, use the same entry with features = ["nightly"] instead.

How does parking_lot's mutex compare to std::sync::Mutex?

The README states parking_lot::Mutex requires 1 byte of storage and was measured on x86_64 Linux at 1.5x faster uncontended and up to 5x faster under contention than std::sync::Mutex. It also allows raw unlocking without a guard and supports eventual fairness.

Can parking_lot guards be sent to other threads?

Yes, when the send_guard feature is enabled, the README says lock guards can be sent to other threads. Note that send_guard and deadlock_detection are incompatible and cannot be used together.

Official sources

  1. Amanieu/parking_lot on GitHub
  2. Issues
  3. License: Apache-2.0
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/amanieu-parking-lot.svg)](https://hysenlabs.com/projects/amanieu-parking-lot)