Distributed Locks and Fencing Tokens

A distributed lock can expire while its worker is still running, and that creates a dangerous gap between permission to start an operation and permission to commit its result to shared state.
When a Lease Expires
Imagine worker 𝗔 acquires a Redis-backed lock with a 30-second TTL and begins a slow update, then pauses during garbage collection while the lock expires without the application realizing it.
Worker 𝗕 acquires the same lock, performs a newer update, and commits its result. When A resumes, it can still write its older result because lock expiration does not terminate running code.
Renewing leases helps when a worker is healthy, and checking an ownership token before releasing a lock avoids deleting another worker's lease, but neither action reliably stops a paused worker from resuming later.
Fencing Stale Workers
The stronger design is to assign each successful lock acquisition a monotonically increasing fencing token, generated by a coordinator that preserves ordering even when several workers compete.
Worker 𝗔 carries token 41 into its writes and worker 𝗕 carries token 42. The protected storage must atomically remember the highest accepted token and reject any later operation carrying an older one.
That turns 𝗔's late write into an explicit rejection instead of a silent rollback of 𝗕's newer state, provided the final resource actually enforces the token rather than trusting the lock service.
Enforcing the Boundary
A storage system or external API that cannot compare fencing tokens does not gain this guarantee from Redis alone, so the operation may need a different coordination boundary or a weaker consistency contract.
The architectural distinction matters: a lease controls who can begin work at a point in time, while fencing controls whether that work still has authority when it reaches the resource it wants to change.
AI Disclosure: The ideas and content are my own. I use LLMs to improve clarity and polish my writing.