Distributed Lock Interview Questions: Leases, Fencing Tokens, and Failure Modes

Prepare for distributed lock interviews with leases, fencing tokens, stale-writer protection, Redis and etcd trade-offs, and failure walkthroughs.

Author: PracHub

Published: 8/22/2026

Distributed Lock Interview Questions: Leases, Fencing Tokens, and Failure Modes

August 22, 2026

Quick Overview

Learn a practical distributed lock interview framework covering leases, fencing tokens, stale writers, Redis and consensus-backed coordination, and production failure modes.

Backend EngineerFree

A distributed lock can be acquired successfully and still fail to protect the resource. That is the trap behind many senior backend and system design interviews: the API says lock acquired, but a paused client, expired lease, delayed packet, or failover can still create two writers.

Interviewers are not looking for "use Redis SETNX" as a complete answer. They want you to define the invariant, explain the authority model, walk through stale-owner failures, and show where the protected resource rejects work that no longer has authority.

Use PracHub's system design interview questions to practice these decisions in complete design prompts. This guide gives you a reusable framework for distributed locks, leases, fencing tokens, and the failure modes that separate a plausible answer from a correct one.

Distributed lock interview questions about leases fencing tokens and failure modes

Quick answer: use a seven-step distributed lock framework

Start with correctness rather than a product name. A strong interview answer moves through these seven decisions:

  1. Name the invariant. State exactly what must never happen, such as two schedulers publishing the same billing run.
  2. Question whether a lock is necessary. A database constraint, compare-and-set, partitioned single writer, idempotency key, or queue may protect the invariant more directly.
  3. Define lock scope and authority. Specify the resource key, owner identity, acquisition semantics, and the system that decides who currently owns it.
  4. Use a lease for liveness. Time-bound ownership so a crashed holder cannot block progress forever; define renewal and lease-loss behavior.
  5. Fence stale holders. Issue a monotonically increasing token and make the protected resource reject older tokens.
  6. Walk every ambiguous outcome. Cover timeouts after acquire, delayed renewals, GC pauses, partitions, failover, duplicate release, and process restart.
  7. Operate the protocol. Include contention, wait time, renewal failures, stale-write rejections, token monotonicity, and a safe degradation policy.

The key sentence is: a lease limits how long authority should last, while a fencing token lets the resource reject a client that incorrectly continues after authority has ended.

Start with the invariant, not the lock service

"Only one worker at a time" is too vague. Ask what side effect must be serialized: charging an account, assigning a driver, writing a manifest, running a tenant migration, or acting as the leader for one shard. Then identify the authoritative destination that can enforce the rule.

For a booking system, a unique or exclusion constraint may be stronger and simpler than a separate lock. For a counter, an atomic increment or conditional update may be enough. For queue consumers, partition ownership plus idempotent processing may remove the need for a global mutex.

This distinction also reveals the cost of failure. If duplicate work only wastes CPU, the lock is an efficiency optimization. If duplicate work corrupts money, inventory, or externally visible state, correctness depends on a protocol that remains safe under pauses and partitions.

Lock, lease, and fencing token are different tools

A local mutex assumes the operating system can reliably track one process's threads. A distributed system cannot reliably distinguish a crashed process from a slow process or a delayed network. That uncertainty changes the primitive.

A lease solves abandoned ownership

A lease is a lock with an expiration time. The holder renews it before the TTL ends; if heartbeats stop, the coordination service eventually allows another client to acquire the resource. This restores liveness after a crash.

But expiry does not stop the old process. A long garbage-collection pause, CPU starvation, page fault, network partition, or overloaded event loop can prevent renewal while the process still believes it is inside the critical section. When it resumes, it may send a delayed write after a new owner has taken over.

A fencing token protects the destination

Each successful acquisition returns a strictly increasing token: 41, then 42, then 43. Every protected write carries that token. The database, storage service, worker, or external adapter records the highest token accepted for the resource and rejects any lower token.

The resource is the final authority. A client-side call such as lease.isValid() cannot prove safety because the client may pause immediately after the check. Fencing moves the decision to the place where the side effect becomes visible.

Walk the stale-holder failure timeline

Use a concrete timeline in the interview. Client A acquires invoice:tenant-7 with a 15-second lease and fencing token 81. It reads pending invoices, then experiences a 30-second pause before writing the batch result.

At second 15, the lease expires. Client B acquires the same lock with token 82, completes the batch, and writes token=82. At second 30, Client A resumes and sends its delayed token=81 write.

Without fencing, both clients may succeed even though the lock service behaved exactly as designed. With fencing, the destination compares 81 with the stored maximum 82 and rejects A as stale. The application records the rejection, stops the old attempt, and reconciles any earlier idempotent steps.

Distributed lock lease expiry timeline showing a stale writer rejected by a fencing token

Design the protocol from acquire through release

Acquire ownership atomically

The request includes a resource key, a unique owner or session ID, and a bounded wait policy. The coordination service grants ownership only if the prior lease is absent or expired, then returns the lease ID, expiration information, and fencing token in one logical operation.

Renew conservatively

Renew well before expiration and use a monotonic clock for local elapsed-time decisions. A renewal timeout is an unknown outcome: the request may have committed even though the response was lost. The client should query session state where supported, but it must stop starting new work when it cannot prove ownership.

Choose TTL from the failure-detection objective, expected pause distribution, coordination latency, and recovery cost. A shorter TTL speeds failover but makes false expiry more likely; a longer TTL tolerates pauses but delays recovery after a true crash.

Fence every authoritative side effect

Carry the token through each command that changes the protected resource. Use a conditional write such as "apply only if incoming token is at least the stored token" and update the stored token atomically with the mutation.

If the destination cannot validate tokens, state the limitation. You may still use the lease to reduce duplicate work, but correctness must come from another mechanism such as idempotent operation IDs, a unique constraint, compare-and-set, transactional ownership, or routing all effects through a single authoritative writer.

Release by identity, never by key alone

A stale client must not delete a newer owner's lock. Release should compare the owner or lease ID and remove ownership only when it matches. In Redis, that comparison and delete must be atomic rather than a separate GET followed by DEL.

Failure modes interviewers will probe

Network partitions and coordination failover

A client isolated from the lock service may continue talking to the protected database. A lock store may also fail over to a replica that has not observed the latest ownership record. State which consistency guarantee the lock service provides and which side becomes unavailable when quorum is lost.

This is where the topic touches distributed consensus interview questions: consensus orders lock state inside the coordination service. Fencing is still needed when an old holder can create side effects outside that ordered log.

Ambiguous acquire and duplicate requests

The server may grant a lock and crash before returning the response. Retrying with a new identity can create an orphaned acquisition or change queue order. Use a stable request or session identity and a client library whose recovery behavior is defined.

Deadlock, starvation, and herd effects

Multiple locks can deadlock unless every client follows one global acquisition order or the design uses a transaction that claims the set atomically. Fairness and bounded waiting matter under contention. Watch the immediate predecessor, as ZooKeeper recipes do, instead of waking every waiter whenever ownership changes.

Redis, etcd, ZooKeeper, or the database?

OptionUseful whenInterview caveat
Redis leaseLow-latency coordination or best-effort duplicate suppressionExplain replication and failover assumptions, safe release, renewal, and how stale writers are fenced.
etcdConsensus-backed coordination with leases, revisions, transactions, and sessionsDo not place high-volume business data in the coordination path; still protect external side effects.
ZooKeeperOrdered ephemeral nodes, leader election, and contention-visible lock queuesHandle session loss and ambiguous create responses; avoid herd effects by watching a predecessor.
Database row or constraintThe invariant already lives in one transactional databasePrefer conditional writes or constraints when they enforce correctness directly; avoid long transactions.

When a distributed lock is the wrong answer

Prefer a unique constraint for uniqueness, optimistic concurrency for low-contention updates, database transactions for one-store invariants, and idempotency keys for retried commands. Partitioning work by key can create a single writer per shard without a lock on every operation.

Worked design: a singleton invoice scheduler

Assume many scheduler replicas can enqueue invoice runs, but only one replica may schedule a given tenant and billing period. The authoritative invariant is one visible run for (tenant_id, billing_period).

First, enforce that invariant with a unique database key. Then use a per-tenant lease to reduce duplicate scans and assign a fencing token to each scheduler generation. A scheduler writes the token and an idempotency key when creating the run. The database accepts the transition only if the token is not older than the tenant's stored generation.

The holder renews in the background and stops claiming new periods when renewal cannot be confirmed. A 40-second pause may let another replica acquire a higher token, but the unique key and token check reject the old replica's delayed insert or update. Workers process runs idempotently, so replay after a timeout does not double-charge.

Monitor lease acquisition latency, renewal margin, expired sessions, rejected stale tokens, duplicate-key conflicts, contention per tenant, and time from billing deadline to run creation. This answer uses the lock for coordination while keeping correctness in the authoritative write path.

Practice distributed lock questions on PracHub

These prompts exercise lease design, fencing, ownership transfer, idempotency, and practical alternatives. They are practice contexts, not predictions of an exact future interview.

PracHub questionPractice focusWhy it helps
Design leader election using Redis leasesLease renewal, split brain, and fencingForces an exact authority and failover protocol instead of a one-line Redis answer.
Design a distributed job scheduler servicePer-shard leadership and fenced enqueueConnects coordinator leases to idempotent jobs, retries, and double-enqueue prevention.
Design a Scheduler for ML Training and Batch Inference JobsAttempt leases and stale-worker fencingTests ownership transfer when long-running workers pause, crash, or report ambiguous outcomes.
Design a Ride-Sharing System (Uber-style Core Platform)Atomic assignment and expiring claimsCompares a lease with conditional writes and single-writer routing for a customer-visible invariant.

A seven-day distributed lock interview plan

Day and focusWhat to do
Day 1: InvariantsWrite three concurrency races and choose a constraint, CAS, queue, single writer, or lock for each.
Day 2: LeasesDesign acquire, renew, expire, and release semantics with explicit timeout behavior.
Day 3: FencingTrace tokens 81 and 82 through a stale-writer timeline and destination-side rejection.
Day 4: Failure injectionWalk GC pauses, partitions, failover, delayed packets, and ambiguous responses.
Day 5: Technology choiceCompare Redis, etcd, ZooKeeper, and a transactional database against one workload.
Day 6: OperationsDefine contention, renewal, stale-token, liveness, and recovery metrics and alerts.
Day 7: Mock interviewDeliver the seven-step framework, then defend why the resource enforces correctness.

Frequently asked questions

What is a distributed lock?

It is a coordination mechanism that grants one client authority over a named resource across processes or machines. Unlike a local mutex, it must handle uncertain liveness, network partitions, delayed messages, service failover, and stale clients.

What is the difference between a lock and a lease?

A lock lasts until release; a lease expires unless renewed. Expiration improves liveness after crashes, but it also allows an old holder to resume after ownership has moved, so lease-based correctness usually needs destination-side fencing.

What is a fencing token?

It is a monotonically increasing generation number returned with each successful acquisition. The protected resource stores the highest generation it has accepted and rejects writes carrying an older token.

Does a Redis lock guarantee mutual exclusion?

The answer depends on the algorithm, deployment, failover behavior, timing assumptions, and protected resource. Explain the exact guarantee instead of saying yes universally. For correctness-critical external writes, add fencing or enforce the invariant directly at the destination.

How do you choose a lease TTL?

Balance failover speed against normal coordination latency and process pauses. Renew well before expiry, measure renewal margin, and design for lease loss rather than assuming the TTL can be longer than every possible pause.

Can fencing tokens prevent every duplicate effect?

No. They reject stale generations only when every authoritative destination validates them atomically. You still need idempotency for retries within the same generation and reconciliation for ambiguous multi-step workflows.

Final takeaway

A strong distributed lock interview answer does not end at acquisition. It proves what happens when the holder pauses, the lease expires, a new owner acts, and the stale holder resumes. The protected resource, not the hopeful client, must reject obsolete authority.

Practice that reasoning with PracHub's system design question bank. For every prompt, name the invariant, decide whether a lock is necessary, draw the stale-owner timeline, and place the final correctness check where the side effect commits.

Sources and Further Reading

Research note: This guide was checked on August 22, 2026. Coordination products and client libraries differ in their safety, liveness, failover, and session guarantees; verify the exact version and deployment used in an interview scenario.


Comments (0)