valkey icon indicating copy to clipboard operation
valkey copied to clipboard

[NEW] Add DELIFEQ command

Open LinusU opened this issue 6 months ago • 13 comments

Opening this for early feedback. Since the code is very short and sweet, I figured I might as well attach it to this feature request. I also started out with just trying to add IFEQ to the existing DEL command, and figured it could just be a small follow up to #1324, but it required a new command for reasons described below.

The problem/use-case that the feature addresses

A very common operation when using Redis to synchronize distributed locks is to remove a key, but only if the value matches a specific string. This pattern is frequently used in distributed locking algorithms like Redlock. The conditional delete prevents a client from inadvertently releasing a lock it doesn’t own—e.g., when a timeout or retry causes overlapping or stale attempts.

Today, this logic is typically implemented using a small Lua script like:

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

However, using scripts adds a layer of complexity and overhead. Having this logic as a built-in Redis command improves simplicity, reliability, and performance. It also complements SET key IFEQ value very nicely.

Description of the feature

This feature introduces a new command: DELIFEQ key value.

The command deletes the given key only if its current value is equal to the provided value. It returns:

  • 1 if the key was removed (i.e., it existed and matched the value),
  • 0 otherwise (key did not exist, or the value did not match).

Example:

SET foo test
DELIFEQ foo test   # returns 1, key is deleted

SET foo nope
DELIFEQ foo test   # returns 0, key remains

Alternatives you've considered

I first started out with trying to add an IFEQ modifier to the existing DEL command, see the work in progress code here:

https://github.com/valkey-io/valkey/compare/unstable...LinusU:valkey:lu-del-ifeq

However, since DEL currently accepts any number of keys to delete, it would cause ambiguity: should DEL foo IFEQ bar delete the three keys foo, IFEQ, and bar, or should it remove the key foo if its value is equal to bar?

I assumed that this breaking change would be unacceptable, so I looked into making it a separate command instead.


Another alternative could be to add an IFEQ modifier to GETDEL, since that command only takes a single key. But it's unnecessary to return the value, since the caller already knows what it is. It would probably be a bit harder to discover in the documentation as well.


Another idea would be to modify DEL to only accept a single key, and either introduce a new command for batch deleting keys, or delegating that to MULTI. That would be a (very) breaking change though 😅

Additional information

  • This command complements SET key IFEQ value, as added in #1324
  • Can serve as a building block for safer, simpler distributed systems
  • Could be extended in the future (e.g., IFNE, IFGT, etc.) but the equality check (IFEQ) covers the vast majority of current locking use cases
  • Implementation is minimal. It's essentially a conditional check followed by an existing DEL op

LinusU avatar Apr 18 '25 09:04 LinusU