Locks in Redis: when they're safe

Distributed systems Senior Python 3.13+ PostgreSQL 17+ Reviewed By Best Latest Apps

Pick the fix

Which release is safe?

Options
Hint 1 of 1

What if our lock already expired and someone else holds it?

Choose an answer, then open Show answer below to check it.

Show answer

Answer: A A Lua script that deletes the key only if its value equals our random token

Correct. Compare and delete happen atomically on the server.

Each holder stores a random token as the lock value. Releasing must check it is still our token and delete in one atomic step, which a Lua script does on the server.

Why not the others?
  • B DEL lock:job. Can delete a lock another worker acquired after ours expired.
  • C GET lock:job in the app, then DEL if it matches. Two round trips: the lock can change hands in between.
  • D Let it expire; never release. Safe but slow: other workers wait the full expiry.

30-second answer

It's a fine lock for efficiency, where an occasional double run only wastes work. Set it with a random value and release it only if the value still matches, using a small Lua script, so you never delete someone else's lock. It isn't safe for correctness: the holder can pause past the expiry, and a Redis failover can lose the key. If two holders would corrupt data, use fencing tokens checked by the storage or a database constraint.

Practise saying it · 35 s. No recording, just a timer

Is a Redis lock safe?

Say your answer out loud, then check which of these points you covered:

  • SET NX PX with random value
  • Atomic compare-and-delete
  • Fine for efficiency
  • Not for correctness without fencing

Deep dive

Release must compare and delete in one server-side step: a short Lua script reads the key and deletes it only when the stored value is still your token.

Redlock (several independent Redis nodes) is debated; it still relies on timing assumptions and has no fencing token.

A database row lock (SELECT ... FOR UPDATE SKIP LOCKED) is often simpler when the work is in that database anyway.

Set the expiry from the worst-case job time, and extend it while working if needed.

Common mistakes

  • DEL lock:job without checking the value.
  • SETNX then EXPIRE as two commands; a crash in between leaves a lock that never expires.
  • Using a Redis lock to guard payments without fencing.

Senior take & follow-ups

Give the right command and release script, then separate efficiency from correctness locks.

Follow-up questions

Think of your answer first, then open the hint.

  1. Why the random value?

    Show hint

    So you only release a lock you still hold.

  2. Lock for efficiency vs correctness?

    Show hint

    Efficiency: duplicates waste work. Correctness: duplicates break data.

Suggest a fix if something here is wrong or out of date.