← Notes

Redis Distributed Locks Explained

· 1 min read

A distributed lock is just a key that only one process can create. In Redis that’s SET key value NX PX ttlNX makes it fail if the key exists, PX gives it a deadline so a crashed holder can’t keep the lock forever.

ok, err := rdb.SetNX(ctx, "lock:invoices", token, 30*time.Second).Result()
if err != nil || !ok {
    return ErrLocked
}
defer release(ctx, rdb, "lock:invoices", token)

The part people get wrong

Releasing with a plain DEL is a bug. If your work ran past the TTL, the lock already expired and someone else holds it — your DEL deletes their lock. Store a random token as the value and delete only if it still matches, which has to be atomic:

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

Rules of thumb

  • TTL should be longer than the worst-case run time, not the average.
  • If the work can outlive the TTL, you need a watchdog that extends it.
  • A single-node Redis lock is best-effort. If correctness genuinely depends on mutual exclusion, put the guarantee in the database instead.