advanced

Distributed locks caveats

Treat Redis locks as leases with fencing, timeout, clock, failover, and idempotency concerns, not a magic mutex.

A Redis lock is usually a lease: `SET resource:lock <token> NX EX <ttl>` — only one holder until TTL expires. It is not a magic cluster-wide mutex; correctness depends on timeout, token verification, fencing, failover behavior, and idempotent workers.

					// Acquire
const token = crypto.randomUUID()
const ok = await redis.set('lock:invoice:9', token, 'NX', 'EX', 30)
if (!ok) throw new Error('busy')

// Release — compare token before DEL (Lua for atomicity)
const script = `
  if redis.call("GET", KEYS[1]) == ARGV[1] then
    return redis.call("DEL", KEYS[1])
  else
    return 0
  end`
await redis.eval(script, 1, 'lock:invoice:9', token)
				

| Risk | Mitigation | |------|------------| | Process pause > TTL | Short work units; extend lease carefully | | Delete wrong lock | Token check in Lua before DEL | | Duplicate execution after expiry | Idempotency keys; fencing tokens to DB | | Failover loses exclusivity | Redlock debate — know cluster limits | | Clock skew | Prefer TTL leases over wall-clock assumptions |

Redlock (multiple independent Redis nodes) reduces some split-brain scenarios but adds complexity and is debated — many teams prefer a dedicated coordination service or database constraints for hard invariants.

On interviews: never claim "exactly-once" from Redis alone; explain lease duration, safe release, and what happens if the worker dies mid-task.

Common pitfalls: `DEL` without token check; long critical sections under one lock; locks without idempotency; using locks where unique constraints or optimistic locking suffice.

The trade-off is low-latency coordination versus fragile correctness edges — Redis locks coordinate best-effort work distribution; hard invariants belong in the data store with fencing.

Checklist:

  • Use `SET NX EX` with unique token.
  • Release with compare-and-del in Lua.
  • Keep leased work shorter than TTL.
  • Pair locks with idempotency or fencing.