Glossary

Distributed lock: coordinating work across processes and servers

A lock limits concurrent critical work. It is neither a database lock nor an absolute guarantee that a business operation is correct.

Short definition

One holder for clearly defined work.

It is useful when two application instances can start the same scheduled job, for example, or when multiple workers synchronise the same inventory. The goal is mutual exclusion: within the chosen guarantee, only one lock holder should work.

A lock operates within a limited time window. It must therefore account for a process crash, network delay, execution pause, and expiration. The work result should have its own duplicate protection even when a lock precedes it.

Use cases

When coordination makes sense

The lock should be as narrow as possible and tied to a specific shared resource.

  • one scheduled job across multiple servers
  • synchronisation of a particular warehouse or marketplace account
  • a product-batch import that must not modify the same data concurrently
  • limiting an expensive report recalculation
  • coordinating workers when the queue does not do so itself

Practical example

Synchronising warehouse-42 inventory

Two worker instances receive the same scheduling signal. Worker A attempts to acquire lock:stock-sync:warehouse-42 with SET, a random token, NX, and PX 30000. Worker B fails and ends the job or schedules a controlled retry.

A loads supplier data and writes the changes. The inventory write must remain safe during a second event: a constraint, state transition, or idempotency key protects the resulting state. If A continued after expiration, it must not delete the lock held by B or overwrite newer data.

Two-process sequence

Worker A and Worker B compete for the same warehouse

A TTL improves availability after a crash, but also creates the risk of a late, stale lock holder.

  1. A acquires the lock Redis atomically creates a key with token A and a TTL of thirty seconds, for example.
  2. B fails The key exists, so SET … NX fails; B must not delete a lock it does not own.
  3. A works The critical section should be short. When extending the lease, A verifies that it is still the owner.
  4. The TTL expires A may be paused. B then acquires a new lock with a different token.
  5. Stale owner The late A must not unlock B or overwrite a newer state; critical targets can use a fencing token.

Key characteristics

Tokens, TTL, and atomic conditions

The mechanism must distinguish the lock owner from another attempt to perform the same work.

SET NX PX

In Redis, basic lock acquisition can be performed atomically with SET key token NX PX ttl: the key is created only when absent and receives an expiration.

Owner token

A random unique value identifies one acquisition attempt. A plain DEL is incorrect: a late process could delete a lock acquired by someone else after expiration.

Lease and extension

The TTL prevents a permanent block after a crash. Extension must compare the token and occur atomically; indefinite extension harms availability.

Fencing token

A monotonically increasing number must come from an authoritative source of truth. The target service compares it on write and rejects an older command; only this provides stronger stale-owner protection than a token alone.

Benefits and limitations

Useful coordination, not a universal safeguard

Benefits

  • limits conflicting and expensive concurrent work
  • the TTL eventually releases the resource after the holder crashes
  • allows one job to run across multiple instances
  • defines the critical section and its genuinely shared resource

Common mistakes

  • DEL without checking the owner token
  • holding a lock through a long import, HTTP wait, or user interaction
  • one global lock for the entire online store instead of a specific resource
  • using a lock instead of a constraint and idempotence

Scope

Choose a mechanism proportionate to the required guarantee.

A database constraint or single-run scheduler may be enough for a short job. A Redis lock is appropriate for a narrow critical section, such as one warehouse or marketplace account.

Convenient lock APIs are not enough for sensitive coordination. Stale owners, failover, fencing tokens, and whether the target store can reject an outdated write all need to be assessed.

What to consider

A lock should be measurable and short-lived

Before introducing one, verify how the system handles both failed acquisition and a holder crash.

  • an unambiguous lock key for the specific resource
  • a random owner token and conditional release
  • a TTL matching the real critical section
  • measurement of contention, expiration, and holding time
  • an idempotent result write and database protection

Common questions

What a distributed lock guarantees

Is a Redis lock the same as SETNX?

No. SETNX is an older command for conditional key creation. A modern design uses SET with NX and expiration, an owner token, and safe release.

Why not simply delete the lock with DEL when finished?

The original process may have been paused. Its TTL expired and another process acquired the lock; a late DEL would delete a lock belonging to someone else.

Does a lock guarantee exactly-once message processing?

No. A message may be delivered again and a client may repeat a request. The resulting state needs idempotence and usually database protection.

Do I need to use Redlock?

Not necessarily. One Redis instance with a TTL may be appropriate for less critical coordination. Higher consistency requires assessing failover, network partitions, and fencing tokens.

How I use the principle in practice

I design job coordination alongside safeguards for the resulting state.

The public scheduling project demonstrates principles for scheduling jobs across servers, testing, and resilience to concurrency.

Request a call

I will call you on the next working day between 9:00 and 17:00.

You can also call me directly.

+420 605 181 728

Leave your phone number and send a callback request.

By sending, you agree to processing your data in order to handle your request.