LMOVE(3valkey)

πŸ“¦
version 9.0.6 Β· 2 versions
, in fedora 44

πŸ’– LMOVE β€” like, the manual page but make it make sense πŸ’–

okay bestie, sit down, hydrate, because we're talking about LMOVE from the Valkey Command Manual and honestly? she ate. 🫢


✨ NAME ✨

lmove β€” returns an element after popping it from one list and pushing it to another. and yes, it deletes the list if the last element was moved. πŸ’…


✨ SYNOPSIS ✨

LMOVE source destination <LEFT | RIGHT> <LEFT | RIGHT>

✨ DESCRIPTION ✨

okay so here's the vibe: LMOVE atomically returns and removes the first/last element (head/tail, depends on the wherefrom argument, obviously) of the list stored at source, and then pushes that element as the first/last element (head/tail, depends on the whereto argument) of the list stored at destination. no cap. πŸ¦‹

for example: imagine source is holding the list a,b,c, and destination is holding the list x,y,z. you run LMOVE source destination RIGHT LEFT and boom β€” source ends up holding a,b and destination ends up holding c,x,y,z. iconic behavior honestly. ✨

if source does not exist, the value nil is returned and no operation is performed. nothing happens. zero drama. πŸ’€

if source and destination are the same, the operation is equivalent to removing the first/last element from the list and pushing it as first/last element of the list, so it can be considered as a list rotation command (or a no-op if wherefrom is the same as whereto). literally just spinning the list around, main character energy. 🌈

this command comes in place of the now deprecated valkey-rpoplpush(7) RPOPLPUSH. doing LMOVE RIGHT LEFT is equivalent. (deprecated = old news bestie, we don't do that anymore, use the new one πŸ’…)


✨ REPLY ✨

valkey-protocol(7) Bulk string reply: the element being popped and pushed. πŸ’–


✨ COMPLEXITY ✨

O(1) β€” constant time, she's fast, she's efficient, we love her. ⭐


✨ ACL CATEGORIES ✨

  • @list
  • @slow
  • @write

✨ HISTORY ✨

  • Available since: 6.2.0 πŸŽ€

✨ EXAMPLES ✨

127.0.0.1:6379> RPUSH mylist "one"
(integer) 1
127.0.0.1:6379> RPUSH mylist "two"
(integer) 2
127.0.0.1:6379> RPUSH mylist "three"
(integer) 3
127.0.0.1:6379> LMOVE mylist myotherlist RIGHT LEFT
"three"
127.0.0.1:6379> LMOVE mylist myotherlist LEFT RIGHT
"one"
127.0.0.1:6379> LRANGE mylist 0 -1
1) "two"
127.0.0.1:6379> LRANGE myotherlist 0 -1
1) "three"
2) "one"

🧚 Pattern: Reliable queue 🧚

so Valkey is often used as a messaging server to implement processing of background jobs or other kinds of messaging tasks. a simple form of queue is often obtained by pushing values into a list on the producer side, and waiting for those values on the consumer side using valkey-rpop(7) RPOP (using polling), or valkey-brpop(7) BRPOP if the client is better served by a blocking operation. πŸ‘‘

however β€” and this is the important part, bestie β€” in this context the obtained queue is not reliable, because messages can be lost. for example in the case there is a network problem, or if the consumer crashes just after the message is received but it is still to process. 😭

LMOVE (or valkey-blmove(7) BLMOVE for the blocking variant) offers a way to avoid this problem: the consumer fetches the message and at the same time pushes it into a processing list. it will use the valkey-lrem(7) LREM command in order to remove the message from the processing list once the message has been processed. periodt. πŸ’…

an additional client may monitor the processing list for items that remain there for too much time, and will push those timed out items into the queue again if needed. teamwork, fr fr. 🫢


πŸ¦‹ Pattern: Circular list πŸ¦‹

using LMOVE with the same source and destination key, a client can visit all the elements of an N-elements list, one after the other, in O(N) without transferring the full list from the server to the client using a single valkey-lrange(7) LRANGE operation. efficiency queen. πŸ‘‘

the above pattern works even in the following conditions:

  • There are multiple clients rotating the list: they'll fetch different elements, until all the elements of the list are visited, and the process restarts. πŸ”„
  • Even if other clients are actively pushing new items at the end of the list. πŸ”₯

the above makes it very simple to implement a system where a set of items must be processed by N workers continuously as fast as possible. an example is a monitoring system that must check that a set of web sites are reachable, with the smallest delay possible, using a number of parallel workers. 🌸

note that this implementation of workers is trivially scalable and reliable, because even if a message is lost the item is still in the queue and will be processed at the next iteration. slay. ✨


✨ SEE ALSO ✨

blmove(3valkey), blmpop(3valkey), blpop(3valkey), brpop(3valkey), brpoplpush(3valkey), lindex(3valkey), linsert(3valkey), llen(3valkey), lmpop(3valkey), lpop(3valkey), lpos(3valkey), lpush(3valkey), lpushx(3valkey), lrange(3valkey), lrem(3valkey), lset(3valkey), ltrim(3valkey), rpop(3valkey), rpoplpush(3valkey), rpush(3valkey), rpushx(3valkey)


and that's the whole page bestie, mwah πŸ’‹ this was version 9.0.0, dated 2025-10-21 β€” go forth and LMOVE responsibly, ily πŸŽ€πŸ’–βœ¨

πŸ“¦ where this page comes from