iChengHub
HomeBlogsToolsLinksAbout
ZH
Submit / Wish
iChengHub
ICP License: 2025085990-1
© 2026 iChengHub. All rights reserved.
© 2026 iChengHub. All rights reserved.
ICP License: 2025085990-1
Home/Blog/What Are the Alternatives to Redis for Implementing Distributed Locks? What Are Their Pros and Cons?

What Are the Alternatives to Redis for Implementing Distributed Locks? What Are Their Pros and Cons?

Redis2026-09-021

Concise Answer

Besides Redis, common distributed lock implementations include databases, ZooKeeper, etcd, and Consul.

  • Database: Requires no additional middleware and is suitable for low-frequency, low-contention scenarios, but it can place significant pressure on performance and database connections under high concurrency.
  • Redis: Offers low latency, high throughput, and a mature ecosystem, making it suitable for high-concurrency scenarios. However, lock safety requires extra consideration during primary-replica failover, lock expiration, and similar situations.
  • ZooKeeper: Implements locks using ephemeral sequential nodes and the Watch mechanism. It is well suited to scenarios that require reliable coordination, fair queuing, and Leader Election, but deployment and operational costs are relatively high.
  • etcd: Implements locks using Lease, Revision, Transaction, and the Lock API. It provides strong consistency and a mature cloud-native ecosystem, making it especially suitable for infrastructure scenarios such as Kubernetes.
  • Consul: Implements locks using KV and Session. It is a good fit for systems that already use Consul for service discovery, but WAN Gossip should not be understood as a mechanism that synchronizes a global lock across data centers.

In practice, there is no universally "best" distributed lock solution. The choice should be based on consistency requirements, performance, business tolerance for failures, existing infrastructure, and operational complexity.


Extended Analysis

Distributed locks solve mutual exclusion problems when multiple processes, service instances, or nodes access a shared resource concurrently.

A reliable distributed lock should usually account for at least the following goals:

  1. Mutual exclusion: Ideally, only one client should enter the critical section at a time.
  2. Deadlock prevention: If a client crashes or loses connectivity, the lock should eventually be released.
  3. Ownership validation: A client must not accidentally release a lock held by another client.
  4. Fault tolerance: Network partitions, node failures, primary-replica failover, and similar failures must be considered.
  5. Business-level safeguards: Critical business correctness should not depend solely on the lock. Idempotency, transactions, CAS, unique constraints, or fencing tokens should also be used when appropriate.

Database-Based Solutions

Common ways to implement distributed locking with a database include:

  • Competing for a lock row through a unique index or unique constraint;
  • Using a dedicated lock table to store fields such as owner and expiration time;
  • Using SELECT ... FOR UPDATE inside a transaction for pessimistic mutual exclusion;
  • Using database-provided Advisory Locks;
  • Using version numbers or conditional updates for optimistic concurrency control when the actual requirement is only to prevent concurrent overwrites.
Multiple Requests
       ↓
Compete for the Same Key in Redis
       ↓
     SET NX
   ┌─────────────┐
 Success       Failure
    ↓              ↓
Lock Acquired   Key Already Exists

Note that optimistic locking is a concurrency-control mechanism and is not equivalent to a traditional distributed mutual-exclusion lock.

For example:

UPDATE product
SET stock = stock - 1,
    version = version + 1
WHERE id = 1
  AND version = 10;
SQL

This SQL statement uses a conditional update so that only the row with the expected version can be modified. It is essentially CAS-style concurrency control, not the mutual-exclusion semantics of "Client A acquires the lock and Client B must wait."

Advantages of Database-Based Solutions

The biggest advantage of database-based locking is architectural simplicity.

If the application already depends on a database such as MySQL or PostgreSQL, there is no need to introduce additional infrastructure such as Redis, ZooKeeper, or etcd. The existing database can be used directly for low-frequency distributed coordination.

Databases can also use transactions, unique constraints, and row locks to provide relatively reliable mutual exclusion within a single-primary database and clearly defined transaction boundaries.

For example, a unique index can be used to compete for a lock:

CREATE TABLE distributed_lock (
    lock_name VARCHAR(128) PRIMARY KEY,
    owner VARCHAR(128) NOT NULL,
    expire_at DATETIME NOT NULL
);
SQL

Clients then try to insert the same lock_name:

INSERT INTO distributed_lock(lock_name, owner, expire_at)
VALUES ('order_job', 'node-a', NOW() + INTERVAL 30 SECOND);
SQL

If a row with the same lock name already exists, the unique constraint prevents a second client from inserting it.

Limitations of Database-Based Solutions

Database locks usually involve:

  • SQL execution;
  • Index maintenance;
  • Transactions;
  • Persistent storage;
  • Database connections;
  • Row-lock or table-lock contention.

As a result, latency and throughput are usually worse than memory-based solutions such as Redis under heavy lock contention.

If a transaction holds a lock for too long, it can also cause:

  • Long-lived database connection usage;
  • More lock waits;
  • Transaction buildup;
  • Connection-pool exhaustion;
  • Overall database performance degradation.

Database-based solutions must also handle abnormal client termination correctly.

If an implementation simply inserts a lock row without an expiration or cleanup mechanism, a client crash may leave behind a permanent lock.

In addition, the fact that a database provides ACID properties does not mean that every distributed database topology automatically provides strict distributed-lock consistency.

If the database uses:

  • Asynchronous primary-replica replication;
  • Automatic Failover;
  • Multi-primary architecture;
  • Read/write splitting;

you still need to analyze how replication lag and failover affect lock state.

Suitable Scenarios

Database locks are better suited to:

  • System configuration changes;
  • Scheduled-job control;
  • Back-office approvals;
  • Low-frequency administrative operations;
  • Low-contention internal tasks;
  • Simple systems that should avoid introducing extra infrastructure.

For high-concurrency, low-latency scenarios such as flash sales or real-time trading, Redis, ZooKeeper, or etcd is usually a better choice.


Redis-Based Solutions

Redis is one of the most common distributed lock implementations in real-world systems.

A Redis single-instance distributed lock typically uses the SET command to perform all of the following atomically:

  1. Write only if the key does not already exist;
  2. Store a unique lock-owner identifier;
  3. Set an automatic expiration time.

For example:

SET order:123:lock 6b692918-2cab-4dc0-b360-481db67d4731 NX PX 30000

Where:

  • NX: Set the key only if it does not already exist;
  • PX 30000: Set an expiration time of 30 seconds;
  • Value: Use a UUID or another random unique identifier to represent the current lock holder.

You should not execute:

SETNX lock value
EXPIRE lock 30

as two separate commands.

If the client crashes immediately after SETNX succeeds but before EXPIRE runs, the lock may remain forever.

Safely Releasing a Redis Lock

When releasing a Redis lock, you must not simply run:

DEL order:123:lock

because the current client's lock may already have expired and been acquired by another client.

For example:

Client A acquires the lock
        ↓
Client A pauses for a long time
        ↓
A's lock TTL expires
        ↓
Client B acquires the same lock
        ↓
Client A resumes and executes DEL
        ↓
Client B's lock is deleted by mistake

Therefore, the lock owner's identity must be validated before release.

A Lua script can atomically perform "compare Value" and "delete Key":

if redis.call("get", KEYS[1]) == ARGV[1] then
    return redis.call("del", KEYS[1])
else
    return 0
end
lua

The key may be deleted only when the unique Token stored in the lock matches the Token held by the current client.

Advantages of Redis

Redis lock operations primarily happen in memory, so they usually provide:

  • Low latency;
  • High throughput;
  • A simple API;
  • A mature client ecosystem.

For example, Redisson in Java already provides:

  • Automatic lock renewal;
  • Reentrant locks;
  • Fair locks;
  • Read/write locks;
  • MultiLock;
  • RedLock and other advanced capabilities.

This makes Redis very suitable for high-frequency, low-latency business coordination.

Risks of Redis

One of the biggest concerns with Redis distributed locks is primary-replica failover.

Typical Redis primary-replica replication is asynchronous:

Client A
   ↓
Primary writes the lock
   ↓
The lock has not yet been replicated to the Replica
   ↓
Primary fails
   ↓
Replica is promoted to the new Primary
   ↓
Client B acquires the same lock

At this point, Client A and Client B may both believe they successfully hold the lock.

Therefore:

Atomic commands on a single Redis instance can correctly implement lock operations on that node, but if asynchronous primary-replica replication is used for Failover, you cannot simply assume that the lock can never be lost.

Redis has proposed the Redlock algorithm, which uses multiple independent Redis instances to reduce the impact of a single-node failure.

However, Redlock's safety model remains controversial in the distributed-systems community.

A more robust engineering principle is:

Do not treat a Redis distributed lock as the only line of defense for business correctness.

For critical data such as inventory, orders, and payments, also use:

  • Unique constraints;
  • CAS;
  • Database transactions;
  • Idempotency;
  • Fencing tokens.

Suitable Scenarios

Redis locks are usually suitable for:

  • Flash sales;
  • Duplicate-submission prevention;
  • High-frequency scheduled-job leader selection;
  • Cache rebuilding;
  • Cache stampede prevention;
  • Short-lived mutual exclusion inside microservices;
  • Latency-sensitive workloads.

ZooKeeper-Based Solutions

ZooKeeper is a classic distributed coordination system and is well suited to implementing distributed locks, Leader Election, configuration coordination, and similar mechanisms.

The classic ZooKeeper distributed lock implementation uses:

EPHEMERAL + SEQUENTIAL

That is, ephemeral sequential nodes.

For example, if multiple clients try to acquire a lock under:

/locks/order

they may create:

/locks/order/lock-00000001
/locks/order/lock-00000002
/locks/order/lock-00000003

Each client retrieves the child nodes and checks:

Is the node I created the one with the smallest sequence number?

If yes, it acquires the lock.

If not, it watches its immediate predecessor.

For example:

lock-00000001   ← holds the lock
lock-00000002   ← watches 00000001
lock-00000003   ← watches 00000002

When:

lock-00000001

is deleted, only:

lock-00000002

needs to be notified to compete again.

This design avoids the severe thundering-herd effect that would occur if all clients watched the same node.

Ephemeral Nodes and Sessions

The lifecycle of a ZooKeeper ephemeral node is bound to a Session.

If a client exits normally or its Session eventually expires, ZooKeeper automatically deletes the ephemeral node created by that client.

Therefore:

Client A
   ↓
Creates EPHEMERAL_SEQUENTIAL
   ↓
Acquires the lock
   ↓
Client A crashes / Session expires
   ↓
ZooKeeper deletes the ephemeral node
   ↓
The next client acquires the lock

This mechanism handles the problem of locks not being released after client crashes very well.

Note:

A brief network disruption does not immediately invalidate a Session.

If the client reconnects and restores the Session within sessionTimeout, the ephemeral node can remain.

ZooKeeper Consistency Semantics

ZooKeeper should not be simplistically described as:

All nodes always see exactly the same state at every moment.

ZooKeeper provides globally ordered writes and strong consistency semantics, but ordinary reads may be served by the Server to which the client is currently connected, so a read may return slightly stale data.

The ZooKeeper lock protocol works reliably because of:

  • Globally ordered updates;
  • Ephemeral sequential nodes;
  • Sessions;
  • Watches;
  • A correct lock acquisition protocol.

It is not because "every arbitrary read from every node is strictly linearizable."

Advantages of ZooKeeper

ZooKeeper is very well suited to distributed coordination:

  • Ephemeral nodes are automatically released;
  • Sequential nodes naturally support fair queues;
  • Watches avoid frequent polling;
  • Recipes for locks, Leader Election, and similar patterns are mature.

With sequential nodes, contenders can be ordered by sequence number, making FIFO-style fair locks natural to implement.

Disadvantages of ZooKeeper

ZooKeeper writes go through a consistency protocol, so compared with a single-node in-memory Redis operation:

  • Latency is usually higher;
  • Lock throughput is usually lower;
  • Performance is more sensitive to network and disk conditions.

Actual performance depends on:

  • Number of cluster nodes;
  • Disk performance;
  • fsync latency;
  • Network RTT;
  • Number of Watches;
  • Number of clients;
  • Read/write ratio;
  • Degree of lock contention.

Therefore, ZooKeeper lock performance should not be described using a single fixed QPS number.

A ZooKeeper cluster also requires operational attention to:

  • JVM;
  • Snapshots;
  • Transaction Logs;
  • Disk I/O;
  • Sessions;
  • Node monitoring.

Operational cost is usually higher than Redis.

Suitable Scenarios

ZooKeeper is suitable for:

  • Leader Election;
  • Distributed task scheduling;
  • Strong coordination scenarios;
  • Fair locks;
  • Infrastructure that already uses ZooKeeper;
  • Systems with high requirements for automatic lock release and session semantics.

etcd-Based Solutions

etcd is a CNCF graduated project and one of the most important foundational components of the Kubernetes control plane.

etcd uses the Raft consensus algorithm to maintain consistent state.

When building distributed locks with etcd, you typically use:

  • Lease;
  • Revision;
  • Transaction;
  • Compare-and-Swap;
  • Watch;
  • Lock API.

Lease

A Lease manages the lifecycle of Keys.

For example, a client creates a Lease with a TTL of 10 seconds:

Lease TTL = 10s

Then binds the lock Key to the Lease:

lock key
   ↓
Lease

The client continuously renews the Lease through KeepAlive.

If the client crashes, loses network connectivity, or can no longer renew:

KeepAlive stops
   ↓
Lease TTL expires
   ↓
The lock Key is automatically deleted

This prevents a crashed client from holding a lock forever.

However, an important point is:

A Lease only manages lifecycle. By itself, it does not provide mutual-exclusion semantics.

A real distributed lock also requires:

  • Transaction;
  • CAS;
  • Revision;
  • The official Lock / concurrency implementation.

Therefore, in production it is generally not recommended to build a complete locking protocol by simply combining:

Put + Lease

If the client library provides an official concurrency / Lock API, prefer the mature implementation.

Revision

In etcd, a Revision is a cluster-wide monotonically increasing logical sequence number.

It can be used to:

  • Determine event ordering;
  • Build a lock contention queue;
  • Implement Watch;
  • Serve as an important foundation for fencing tokens.

For example:

Client A acquires the lock → Revision 101
Client B acquires the lock → Revision 102

A downstream resource can reject requests carrying a Revision smaller than the maximum Revision it has already observed.

This means that even if Client A resumes after a long pause, its stale Token can prevent the old client from continuing to write to a critical resource.

etcd Consistency and Performance

etcd replicates writes through Raft and provides strongly consistent KV semantics.

Compared with Redis, etcd operations usually have higher latency because they go through a consensus protocol.

However, etcd provides highly mature strongly consistent coordination capabilities in cloud-native environments.

Official etcd performance benchmarks show that a three-node cluster can reach tens of thousands of API requests per second with suitable hardware and networking.

Note:

API Benchmark requests/s cannot be directly equated with complete distributed-lock Lock/Unlock TPS.

A complete lock operation may involve:

  • Lease;
  • Transaction;
  • Revision;
  • Watch;
  • Unlock;
  • Network RTT;
  • Lock contention.

Actual lock throughput therefore needs to be benchmarked for the specific workload.

Disadvantages of etcd

A production etcd deployment usually requires at least three nodes to tolerate failures through quorum.

You also need to monitor:

  • Raft;
  • Leader;
  • Network RTT;
  • Disk fsync;
  • DB Size;
  • Compaction;
  • Defragment;
  • Lease;
  • Node health.

As a result, operational complexity is usually higher than with a single-node Redis deployment.

Suitable Scenarios

etcd is especially suitable for:

  • Kubernetes;
  • Cloud-native control planes;
  • Leader Election;
  • Distributed task scheduling;
  • Strongly consistent configuration management;
  • Coordination systems that need Lease + Watch + Revision.

Consul-Based Solutions

Consul is a service-discovery and distributed-coordination system from HashiCorp.

Consul can use:

KV + Session

to implement distributed locks.

A client creates a Session:

Session

and then uses a KV acquire operation to associate a Key with the Session:

lock/order
    ↓
Session A

If the Key is not currently held by another Session, the acquire can succeed.

When the client becomes unavailable or the Session is invalidated, the lock can be released according to the Session configuration.

Consul Session

A Consul Session can be associated with:

  • Node;
  • Health Check;
  • TTL;

and other states.

This allows the lock lifecycle to be tied to the lifecycle of a service instance.

That is convenient for microservice architectures that already use Consul for service discovery.

Correctly Understanding Consul Multi-Data-Center Behavior

Consul supports multi-data-center Federation, but this should not be interpreted as:

A KV lock acquired in one data center is automatically synchronized through WAN Gossip into a global lock shared by all data centers.

The main purposes of WAN Gossip are:

  • Propagating Server Membership information between Data Centers;
  • Helping Servers discover other data centers;
  • Supporting cross-data-center request routing.

It is not a consensus protocol for replicating KV lock state.

Strongly consistent state within each data center is primarily maintained by that data center's own Raft cluster.

If a client needs to operate on a lock in a remote data center, it must explicitly send the request to the target Data Center.

Therefore:

Native Consul multi-data-center support does not mean that WAN Gossip automatically provides a globally synchronized distributed lock.

True cross-region global mutual exclusion still needs to be designed separately based on the business architecture.

Consul Consistency Semantics

Consul state writes are completed through Raft.

However, reads have different consistency modes.

Common modes include:

  • default;
  • consistent;
  • stale.

Default reads provide strong consistency in most cases, but there is a very small window during Leader failover in which stale data may be returned.

If stricter consistent reads are required, explicitly use:

consistent

If slightly stale reads are acceptable in exchange for lower latency, use:

stale

Therefore, a comparison table should not simply label all Consul reads and writes as "linearizable."

Consul Reentrancy Semantics

Consul KV acquire allows the same Session that already holds a lock to acquire it again.

However, this Session-level reacquire is not identical to the thread-level reentrant-lock model used by Java ReentrantLock or Redisson, which typically involves:

Thread ID
+
Hold Count

Therefore, if the application needs:

  • Reentrancy counting;
  • Fair locks;
  • Read/write locks;
  • More complex lock semantics;

additional encapsulation is usually required in the client or application layer.

Suitable Scenarios

Consul locks are better suited for:

  • Microservice architectures that already use Consul extensively;
  • Combining service discovery and coordination;
  • Leader Election;
  • Configuration coordination;
  • Tasks whose lifecycle is closely tied to service health.

Selection Decisions and Practical Recommendations

There is no universally optimal distributed lock solution.

Redis

Suitable for:

  • High throughput;
  • Low latency;
  • Frequent short-lived mutual exclusion;
  • Business systems that already use Redis extensively.

However, the business logic must correctly handle:

  • Lock TTL expiration;
  • Client pauses;
  • Primary-replica failover;
  • Network partitions;
  • Occasional lock invalidation.

ZooKeeper

Suitable for:

  • Distributed coordination;
  • Leader Election;
  • Fair queuing;
  • Task scheduling;
  • Systems that already depend on ZooKeeper.

etcd

Suitable for:

  • Kubernetes;
  • Cloud-native infrastructure;
  • Strongly consistent coordination;
  • Leader Election;
  • Systems that need Lease, Revision, and Watch.

Consul

Suitable for:

  • Systems that already use Consul for service discovery;
  • Tying Sessions to service-instance lifecycles;
  • Coordination tasks inside the Consul ecosystem.

Database

Suitable for:

  • Low-frequency locking;
  • Low contention;
  • Back-office administration;
  • Simple internal systems;
  • Systems that should avoid introducing new infrastructure.

Common Pitfalls and Best Practices

1. Lock Timeout Does Not Match Business Execution Time

Suppose:

Lock TTL = 10 seconds
Business execution = 20 seconds

The following can happen:

Client A acquires the lock
        ↓
Executes for 10 seconds
        ↓
The lock expires automatically
        ↓
Client B acquires the lock
        ↓
A and B execute the critical section concurrently

Best Practices

Possible approaches include:

  • Automatic renewal;
  • A reasonable TTL;
  • Idempotency;
  • CAS;
  • Fencing tokens.

For example, the Redisson Watchdog automatically renews a lock while the business operation still holds it.

However:

Automatic renewal can reduce the probability of lock expiration, but it cannot theoretically eliminate every process pause, network partition, or failover problem.

Critical business logic still needs downstream data constraints as safeguards.


2. Lock Reentrancy

A simple Redis lock:

SET lock token NX PX 30000

does not provide the same reentrant semantics as Java ReentrantLock by default.

If the same thread tries to acquire the same lock again:

Thread A
  ↓
lock()
  ↓
calls methodB()
  ↓
lock() again

it may end up waiting on a lock that it already holds.

Best Practices

If reentrant locking is required, consider:

  • Redisson;
  • A mature client that provides a reentrant mutex;
  • Avoiding nested lock acquisition in application code.

Different middleware may also define "reentrancy" differently, so distinguish between:

  • Thread-level;
  • Process-level;
  • Session-level.

3. GC Pauses, Process Pauses, and Lease Expiration

Languages such as Java and Go both use garbage collection.

Therefore, it is incorrect to say:

Go is a non-GC language.

Go also has a Garbage Collector.

In extreme cases:

  • Full GC;
  • CPU starvation;
  • Container freezing;
  • VM Pause;
  • Operating-system scheduling delays;
  • Debugger pauses;

can all prevent the client from renewing the lock for an extended period.

For example:

Client A acquires the lock
        ↓
A pauses for 60 seconds
        ↓
The Lease expires after 30 seconds
        ↓
Client B acquires the lock
        ↓
Client A resumes

At this point, A may continue operating on the shared resource.

Incorrect Fix

Simply setting a very large TTL:

TTL = 10 minutes

only reduces the probability of the issue. It does not theoretically prove that:

The pause can never exceed 10 minutes

Fencing Token

A more reliable approach is to use a fencing token.

For example:

Client A → token 41
Client B → token 42

The shared resource records:

last_token = 42

When the resumed Client A tries to write again with:

token = 41

the resource sees:

41 < 42

and rejects the operation.

Therefore:

A distributed lock determines "who is currently considered authorized to execute," while a fencing token determines "whether an old client that has already lost execution rights is still allowed to write."

This distinction is especially important for critical scenarios such as payments, inventory, finance, and task scheduling.


4. Fairness of Lock Acquisition

Different solutions provide different fairness properties.

ZooKeeper

ZooKeeper can use:

EPHEMERAL_SEQUENTIAL

to form a FIFO-style contention queue based on node sequence numbers.

This makes it very suitable for implementing fair locks.

etcd

etcd can use:

Revision

to represent event order, and the official Lock implementation can use that ordering to organize lock contention.

Redis

The simplest Redis lock often follows:

Failure
↓
Sleep
↓
Retry

This does not provide a strict FIFO guarantee by default.

If multiple clients retry at the same time, they may also create a:

Thundering Herd

problem.

Best Practices

If the business strongly depends on fair queuing:

  • ZooKeeper;
  • etcd;

are usually easier choices.

If you only need high-performance mutual exclusion and strict fairness is not required:

  • Redis;

is usually simpler.


5. Always Verify Lock Ownership Before Release

In Redis, the lock must store a unique Token:

SET order:lock 550e8400-e29b-41d4-a716-446655440000 NX PX 30000

On release:

GET value
    ↓
Does it equal my token?
    ↓
Yes → DEL
No  → Do nothing

And:

GET + DEL

must not be split into two ordinary commands, because the lock state may change between them.

Use Lua or another atomic conditional-delete mechanism instead.

ZooKeeper and etcd can respectively use:

  • Session + Ephemeral Node;
  • Lease + Lock Key;

to manage lock lifecycles, so locks can be released automatically after abnormal client termination.

However:

Session / Lease binding solves lifecycle management. It does not automatically provide access-control isolation.

Whether another client is allowed to delete a lock node also depends on:

  • ZooKeeper ACL;
  • etcd Authentication / RBAC;
  • Client lock protocol;
  • Application permission design.

6. Do Not Treat a Distributed Lock as an Absolute Safety Barrier

Even after a client successfully acquires a lock, you still need to consider:

Network partition
GC Pause
VM Pause
Lease expiration
Primary Failover
Client timeout
Service restart

Therefore, correctness in critical systems is usually protected by multiple layers:

Distributed Lock
        +
Idempotency
        +
CAS
        +
Database Transaction
        +
Unique Constraint
        +
Fencing Token

rather than:

Distributed Lock
        =
Concurrency problems are impossible

Solution Comparison

DimensionDatabaseRedisZooKeeperetcdConsul
Lock performanceLow to mediumHighMediumMedium to highMedium
Core mechanismUnique constraint / row lock / lock tableSET NX PX + TokenEphemeral sequential node + WatchLease + Revision + Transaction / LockSession + KV Acquire
Consistency characteristicsDepends on database topology and transaction modelAtomic on a single instance; Failover requires additional lock-safety considerationsWrites are globally ordered; ordinary reads may be slightly staleStrongly consistent KV / RaftRaft writes; reads depend on Consistency Mode
Automatic releaseMust be implemented explicitlyTTL / WatchdogSession + Ephemeral NodeLeaseSession
FairnessDepends on implementationNo strict guarantee by defaultWell suited to FIFOOrdered contention can be built with RevisionDepends on implementation
Operational complexityLowLow to mediumHighMedium to highMedium to high
Ecosystem advantageNo additional middleware requiredMature ecosystem and rich client supportMature distributed coordinationKubernetes / cloud-nativeCombines service discovery and coordination
Typical scenariosLow-frequency background tasksFrequent short-lived mutual exclusionLeader Election / task schedulingCloud-native coordinationSystems where Consul is already deployed

Avoid directly comparing distributed lock solutions using a single fixed QPS number. Actual performance depends heavily on hardware, network conditions, lock contention, number of clients, lock hold time, request model, and implementation details. Ordinary KV Benchmarks also cannot be directly equated with complete Lock/Unlock throughput.


Final Recommendations

A practical selection strategy is as follows:

If the System Already Uses Redis Extensively

Prefer Redis.

Suitable for:

  • High concurrency;
  • Low latency;
  • Short-lived mutual exclusion;
  • Workloads where idempotency or data constraints can provide a fallback.

If Mature Distributed Coordination Is Required

Consider ZooKeeper.

Suitable for:

  • Leader Election;
  • Fair locks;
  • Distributed scheduling;
  • Strong coordination systems.

If the System Belongs to the Kubernetes / Cloud-Native Ecosystem

Prefer etcd.

It natively provides:

  • Lease;
  • Revision;
  • Watch;
  • Transaction;
  • Lock;
  • Raft;

making it very suitable for control planes and distributed coordination mechanisms.


If Consul Is Already in Use

You can directly use Consul:

Session + KV

to implement locking.

However, do not assume that because Consul supports multiple data centers, WAN Gossip automatically replicates locks into a cross-region global lock.


If You Only Need Low-Frequency Background Tasks

A database is often sufficient.

There is no need to deploy a new coordination cluster just for a few low-frequency lock operations.


Summary

Redis, databases, ZooKeeper, etcd, and Consul can all be used to implement distributed coordination, but they solve the problem differently and have different safety boundaries.

A simple mental model is:

Database
    ↓
Simple architecture, suitable for low-frequency coordination

Redis
    ↓
High performance, widely used in production

ZooKeeper
    ↓
Mature distributed coordination and fair contention

etcd
    ↓
Strong consistency + cloud-native + Lease / Revision

Consul
    ↓
Session-based coordination within a service-discovery ecosystem

What really matters is not "which lock is the fastest," but:

Whether your business logic remains correct when locks expire, clients pause, networks partition, or nodes fail.

For non-critical workloads, mature client libraries can handle most distributed-lock requirements.

For critical systems such as payments, inventory, finance, and scheduling, you should additionally combine:

  • Idempotency;
  • CAS;
  • Database transactions;
  • Unique constraints;
  • Fencing tokens;

to preserve overall system correctness.

Last updated on·2026-09-02

←Back to ListThe Authoritative Guide to Go Configuration Management: Viper v1.21 Deep Dive and Engineering Practices→
Concise AnswerExtended AnalysisDatabase-Based SolutionsAdvantages of Database-Based SolutionsLimitations of Database-Based SolutionsSuitable ScenariosRedis-Based SolutionsSafely Releasing a Redis LockAdvantages of RedisRisks of RedisSuitable ScenariosZooKeeper-Based SolutionsEphemeral Nodes and SessionsZooKeeper Consistency SemanticsAdvantages of ZooKeeperDisadvantages of ZooKeeperSuitable Scenariosetcd-Based SolutionsLeaseRevisionetcd Consistency and PerformanceDisadvantages of etcdSuitable ScenariosConsul-Based SolutionsConsul SessionCorrectly Understanding Consul Multi-Data-Center BehaviorConsul Consistency SemanticsConsul Reentrancy SemanticsSuitable ScenariosSelection Decisions and Practical RecommendationsRedisZooKeeperetcdConsulDatabaseCommon Pitfalls and Best Practices1. Lock Timeout Does Not Match Business Execution Time2. Lock Reentrancy3. GC Pauses, Process Pauses, and Lease ExpirationFencing Token4. Fairness of Lock Acquisition5. Always Verify Lock Ownership Before Release6. Do Not Treat a Distributed Lock as an Absolute Safety BarrierSolution ComparisonFinal RecommendationsIf the System Already Uses Redis ExtensivelyIf Mature Distributed Coordination Is RequiredIf the System Belongs to the Kubernetes / Cloud-Native EcosystemIf Consul Is Already in UseIf You Only Need Low-Frequency Background TasksSummary