Distributed Lock
A lock that coordinates access to a shared resource across multiple machines. Implemented via Redis (Redlock), ZooKeeper, or etcd. Much harder than local locks.
What is Distributed Lock?
In short
A distributed lock is a coordination mechanism that lets only one process across many machines hold exclusive access to a shared resource at a time, even though those processes do not share memory and communicate over an unreliable network. It is typically built on a system like Redis, ZooKeeper, or etcd that all the machines can agree on.
What a distributed lock actually is
On a single machine, when two threads want to touch the same data, you use a mutex. The operating system guarantees only one thread holds it. A distributed lock solves the same problem, but the competing parties are separate processes running on separate servers that share no memory and only talk over a network that can drop, delay, or reorder messages.
The point is mutual exclusion across the fleet. Say five copies of your service are all running a scheduled job that charges a customer. Without coordination, all five could fire at once and charge the card five times. A distributed lock makes four of them wait or skip while one does the work.
The key fact that makes this hard: the thing holding the lock can die at any moment, and the network can lie. So a real distributed lock is not just a flag in shared storage. It needs an expiry (a lease) so a crashed holder does not block everyone forever, and it needs a way to safely hand the lock to someone else.
How it works under the hood
The simplest correct pattern uses an atomic set-if-not-exists with a timeout. In Redis this is SET resource_key random_token NX PX 30000, which means create the key only if it does not exist and auto-delete it after 30 seconds. The random token is the owner's proof of ownership. To release, the owner runs a small Lua script that deletes the key only if the stored token still matches its own. That match-then-delete must be atomic, otherwise you can delete a lock that already expired and was grabbed by someone else.
ZooKeeper and etcd take a different approach built on consensus. A client creates an ephemeral node, and ZooKeeper deletes that node automatically the moment the client's session disconnects. Clients line up in order and watch the node ahead of them, so the lock is handed off cleanly without polling. Because these systems run a quorum (typically Raft in etcd, Zab in ZooKeeper), they survive node failures and give a consistent view of who holds the lock.
The subtle failure is the paused holder. A process can acquire the lock, then get frozen by a long garbage collection pause or a network partition. Its lease expires, someone else takes the lock, and then the original process wakes up still believing it holds the lock and writes to the resource. The defense is a fencing token: a number that only ever increases, handed out with each lock grant. The protected resource rejects any write carrying a token lower than the highest one it has seen, so the stale holder's write is refused.
When to use it and the trade-offs
Reach for a distributed lock when correctness depends on exactly one actor doing something at a time across machines: a leader running a cron job once, exclusive access to a non-transactional external API, or a migration that must not run twice. It is the wrong tool for high-throughput contention. If thousands of requests fight over one lock, you have serialized your whole system through a single chokepoint, and latency and timeouts pile up.
Before adding a lock, check whether the database can do the job. A unique constraint, an UPDATE ... WHERE version = ? optimistic check, or SELECT FOR UPDATE inside a transaction often removes the need for an external lock entirely and is harder to get wrong. Idempotency keys, where repeating an operation is simply a no-op, can sidestep locking altogether.
The trade-offs are real. Single-Redis locks are fast but lose correctness if that Redis fails over mid-lock. The Redlock algorithm spreads the lock across several independent Redis nodes for better availability, but Martin Kleppmann's well-known critique showed it still does not guarantee safety under clock drift and GC pauses without fencing tokens. ZooKeeper and etcd give stronger guarantees because they are consensus systems, at the cost of more latency and operational weight.
A concrete real-world example
Picture an e-commerce platform with a nightly job that reconciles inventory against a supplier's API. The service runs on eight pods in Kubernetes. The supplier's API is not idempotent, so running the reconciliation twice corrupts stock counts.
Each pod tries to acquire a lock in etcd on the key reconcile/2026-06-14 with a 10 minute lease. etcd's consensus guarantees exactly one pod wins. That pod renews its lease in the background while it works, so the lock never expires mid-run. The other seven see the key already held and exit immediately.
etcd hands the winner a fencing token tied to the lease revision. Every write the pod makes to the internal inventory store includes that token, and the store rejects stale tokens. So even if the winning pod stalls on a long GC pause, its lease lapses, another pod takes over with a higher token, and any late write from the frozen pod is rejected rather than silently overwriting fresh data.
Where it is used in production
Redis
Provides SET NX PX for simple locks and the Redlock algorithm across multiple nodes for higher availability.
etcd
Backs Kubernetes leader election and distributed locks using Raft consensus and lease-bound keys.
Apache ZooKeeper
Powers locks and leader election in Kafka and HBase via ephemeral sequential nodes and watches.
Google Chubby
Google's internal lock service that pioneered coarse-grained distributed locking and inspired ZooKeeper.
Frequently asked questions
- Why can't I just use a normal lock or mutex?
- A mutex only works inside one process on one machine because it relies on shared memory the OS controls. When the competing parties are separate servers with no shared memory, talking over an unreliable network, there is nothing for a mutex to coordinate. A distributed lock provides that shared point of agreement.
- What is a fencing token and why do I need one?
- A fencing token is a number that strictly increases each time the lock is granted. The protected resource records the highest token it has seen and rejects any write with a lower one. This stops a holder that paused (from GC or a network partition) and lost its lease from corrupting data after another process already took the lock.
- Is Redis Redlock safe to use?
- It is fine when the lock is an efficiency optimization, like avoiding duplicate work. It is not safe to rely on for correctness on its own, because clock drift and process pauses can let two clients believe they hold the lock at once. If correctness matters, add fencing tokens or use a consensus system like etcd or ZooKeeper.
- What happens if the process holding the lock crashes?
- That is why every distributed lock uses a lease or an ephemeral node with a timeout. If the holder crashes, the lock auto-expires after the lease window (Redis) or is deleted when the session disconnects (ZooKeeper and etcd), so the resource is not blocked forever and another process can acquire it.
- Should I always reach for a distributed lock?
- No. First check if your database can enforce it with a unique constraint, optimistic version check, or SELECT FOR UPDATE, or whether making the operation idempotent removes the need entirely. Distributed locks add a single chokepoint and new failure modes, so use them only when exclusive cross-machine access is genuinely required.
Learn Distributed Lock hands-on
This page explains the idea. The full lesson lets you step through the ring as servers join and leave, read the implementation, and check yourself with a quiz. It is one of 760+ lessons in the System Design Masterclass, from your first API call to distributed consensus. Eleven Foundation lessons are free, no signup. Lifetime access is ₹499 in India or $7.99 worldwide, one payment, no subscription.
Related lessons
Lessons that touch on Distributed Lock as part of a larger topic.
Distributed Locks
Mutual exclusion across network boundaries. Redlock, ZooKeeper locks, and why they're harder than you think
advanced · distributed systems core
Saga Pattern
Long-lived transactions without distributed locking, orchestration vs choreography for microservices
advanced · distributed systems core
See also
Related glossary terms you might want to look up next.
Deadlock
When two or more transactions are each waiting for the other to release a lock, creating a cycle where none can proceed. Databases detect and break deadlocks by aborting one.
Leader Election
The process of choosing one node in a cluster to coordinate actions. If the leader fails, a new one is elected. Used by Kafka, ZooKeeper, and etcd.
Redis
An in-memory data store used as a cache, message broker, and database. Blazing fast because everything lives in RAM.
CAP Theorem
In a distributed system, you can only guarantee two of three: Consistency, Availability, and Partition tolerance. You must choose your trade-off.
Consensus
The process of getting multiple nodes in a distributed system to agree on a single value. The foundation of distributed databases and coordination services.
Paxos
A family of protocols for solving consensus in unreliable networks. Famously difficult to understand but mathematically proven correct.