Redis BLMOVE Command Explained

In Redis, the BLMOVE command is the blocking variant of LMOVE.

When the specified list contains elements, it atomically returns and removes either the first or last element of the given source list, and pushes the element at either the first or last element of the specified destination list. Whether it’s the first or last element depends on the arguments passed to the command.

The command works the same way when used inside a MULTI/EXEC block.

If the source list is empty, Redis will block the connection until another client pushes to it or until the specified timeout is reached.

The BLMOVE command can be used in place of the BRPOPLPUSH command, which has been deprecated since Redis 6.2.0.

Syntax

The syntax goes like this:

BLMOVE source destination <LEFT | RIGHT> <LEFT | RIGHT> timeout

Where source is the source list and destination is the destination list.

The other arguments determine whether the command removes/pushes the first or last element from/to the lists.

Example

Suppose we create a list like this:

RPUSH scores 1 2 3 4 5 6 7 8 9 10

Result:

(integer) 10

Let’s look at its contents:

LRANGE scores 0 -1

Result:

 1) "1"
 2) "2"
 3) "3"
 4) "4"
 5) "5"
 6) "6"
 7) "7"
 8) "8"
 9) "9"
10) "10"

We can use BLMOVE like this:

BLMOVE scores points LEFT RIGHT 3

Result:

"1"

The result shows us the value that was moved from the source list to the destination list.

Let’s check the contents of our list again to verify:

LRANGE scores 0 -1

Result:

1) "2"
2) "3"
3) "4"
4) "5"
5) "6"
6) "7"
7) "8"
8) "9"
9) "10"

We can see that the first element has gone.

Let’s check the destination list:

LRANGE points 0 -1

Result:

1) "1"

The element has turned up in the destination list.

In my case, the destination list didn’t previously exist. Therefore it was created, and the element was pushed to it.

We can use LEFT RIGHT to remove the last element from the list and push it to the start of the destination list.

BLMOVE scores points RIGHT LEFT 3

Result:

"10"

In this case the last element is removed, and it’s pushed as the first element to the destination list.

Let’s check the lists again.

LRANGE scores 0 -1

Result:

1) "2"
2) "3"
3) "4"
4) "5"
5) "6"
6) "7"
7) "8"
8) "9"

This time the last element has gone.

And the destination list:

LRANGE points 0 -1

Result:

1) "10"
2) "1"

The element is now in the destination list.

Empty Source List

In the previous examples I used 3 for the timeout value. This means that if the source list is empty, the connection will be blocked until three seconds has passed.

Here’s an example that uses an empty source list:

BLMOVE emptylist points RIGHT LEFT 3

Result:

(nil)
(3.06s)

My client waited three seconds before returning nil.

Using a timeout value of zero will block the connection indefinitely.

Circular Lists

It’s possible to use the same key for both the source list and the destination list. Doing this allows the client to visit all the elements of the list without having to transfer the whole list from the server to the client using the LRANGE operation. See the Redis documentation for more information about this technique.