Skip to main content
Redis lists are ordered collections of strings, sorted by insertion order. They are implemented as linked lists, making head and tail operations very fast.

LPUSH

Prepends one or more elements to a list. Creates the key if it doesn’t exist.

Syntax

LPUSH key element [element ...]
key
key
required
The list key. Created if it doesn’t exist.
element
string
required
One or more elements to prepend to the list.
length
integer
The length of the list after the push operations.
Time Complexity: O(1) for each element added, so O(N) to add N elements. History:
  • 2.4.0: Accepts multiple element arguments.

Examples

redis> LPUSH mylist "world"
(integer) 1
redis> LPUSH mylist "hello"
(integer) 2
redis> LRANGE mylist 0 -1
1) "hello"
2) "world"
redis> LPUSH mylist "foo" "bar"
(integer) 4
redis> LRANGE mylist 0 -1
1) "bar"
2) "foo"
3) "hello"
4) "world"

RPUSH

Appends one or more elements to a list. Creates the key if it doesn’t exist.

Syntax

RPUSH key element [element ...]
key
key
required
The list key. Created if it doesn’t exist.
element
string
required
One or more elements to append to the list.
length
integer
The length of the list after the push operations.
Time Complexity: O(1) for each element added, so O(N) to add N elements. History:
  • 2.4.0: Accepts multiple element arguments.

Examples

redis> RPUSH mylist "hello"
(integer) 1
redis> RPUSH mylist "world"
(integer) 2
redis> LRANGE mylist 0 -1
1) "hello"
2) "world"
redis> RPUSH mylist "foo" "bar"
(integer) 4
redis> LRANGE mylist 0 -1
1) "hello"
2) "world"
3) "foo"
4) "bar"

LPOP

Removes and returns the first element of a list.

Syntax

LPOP key [count]
key
key
required
The list key.
count
integer
Number of elements to pop. Returns an array if specified.
element
string
The value of the first element, or nil when key does not exist. If count is specified, returns an array of popped elements.
Time Complexity: O(N) where N is the number of elements returned. History:
  • 6.2.0: Added the count argument.

Examples

redis> RPUSH mylist "one" "two" "three" "four" "five"
(integer) 5
redis> LPOP mylist
"one"
redis> LPOP mylist 2
1) "two"
2) "three"
redis> LRANGE mylist 0 -1
1) "four"
2) "five"

RPOP

Removes and returns the last element of a list.

Syntax

RPOP key [count]
key
key
required
The list key.
count
integer
Number of elements to pop. Returns an array if specified.
element
string
The value of the last element, or nil when key does not exist. If count is specified, returns an array of popped elements.
Time Complexity: O(N) where N is the number of elements returned. History:
  • 6.2.0: Added the count argument.

Examples

redis> RPUSH mylist "one" "two" "three" "four" "five"
(integer) 5
redis> RPOP mylist
"five"
redis> RPOP mylist 2
1) "four"
2) "three"
redis> LRANGE mylist 0 -1
1) "one"
2) "two"

LRANGE

Returns a range of elements from a list.

Syntax

LRANGE key start stop
key
key
required
The list key.
start
integer
required
The starting index (0-based). Negative indices count from the end (-1 is last element).
stop
integer
required
The ending index (inclusive). Negative indices count from the end.
elements
array
List of elements in the specified range.
Time Complexity: O(S+N) where S is the distance of start from HEAD for small lists, and N is the number of elements in the range.

Examples

redis> RPUSH mylist "one" "two" "three"
(integer) 3
redis> LRANGE mylist 0 0
1) "one"
redis> LRANGE mylist -3 2
1) "one"
2) "two"
3) "three"
redis> LRANGE mylist -100 100
1) "one"
2) "two"
3) "three"
redis> LRANGE mylist 5 10
(empty array)

LLEN

Returns the length of a list.

Syntax

LLEN key
key
key
required
The list key.
length
integer
The length of the list, or 0 when key does not exist.
Time Complexity: O(1)

Examples

redis> LPUSH mylist "World"
(integer) 1
redis> LPUSH mylist "Hello"
(integer) 2
redis> LLEN mylist
(integer) 2

Additional List Commands

  • LINDEX: Get element by index
  • LSET: Set element value by index
  • LINSERT: Insert element before or after another
  • LREM: Remove elements by value
  • LTRIM: Trim list to specified range
  • BLPOP: Blocking left pop
  • BRPOP: Blocking right pop
  • RPOPLPUSH: Pop from one list, push to another
  • BRPOPLPUSH: Blocking RPOPLPUSH
  • LMOVE: Move element between lists
  • BLMOVE: Blocking LMOVE
  • LPOS: Find index of element
  • LMPOP: Pop from multiple lists

Use Cases

Message Queue

Implement a simple message queue:
# Producer pushes messages
redis> RPUSH queue:tasks "task1"
(integer) 1
redis> RPUSH queue:tasks "task2"
(integer) 2

# Consumer pops messages
redis> LPOP queue:tasks
"task1"
redis> LPOP queue:tasks
"task2"

Activity Feed

Store user activity with LPUSH and retrieve with LRANGE:
redis> LPUSH user:1000:feed "logged in"
(integer) 1
redis> LPUSH user:1000:feed "viewed profile"
(integer) 2
redis> LPUSH user:1000:feed "posted comment"
(integer) 3
redis> LRANGE user:1000:feed 0 9
1) "posted comment"
2) "viewed profile"
3) "logged in"

Fixed-Size List

Maintain a capped list with LPUSH and LTRIM:
redis> LPUSH mylist "new item"
(integer) 1
redis> LTRIM mylist 0 99
OK

Stack (LIFO)

Use LPUSH and LPOP for stack operations:
redis> LPUSH stack "first"
(integer) 1
redis> LPUSH stack "second"
(integer) 2
redis> LPOP stack
"second"
redis> LPOP stack
"first"

Queue (FIFO)

Use RPUSH and LPOP for queue operations:
redis> RPUSH queue "first"
(integer) 1
redis> RPUSH queue "second"
(integer) 2
redis> LPOP queue
"first"
redis> LPOP queue
"second"

Best Practices

Performance Considerations

  1. Head/Tail Operations: LPUSH, RPUSH, LPOP, RPOP are O(1) - very fast
  2. Index Access: LINDEX is O(N) for middle elements - avoid on large lists
  3. Range Operations: Use LRANGE carefully with large lists
  4. List Size: Monitor list size to prevent unbounded growth

Memory Management

  1. Use LTRIM to maintain fixed-size lists
  2. Set expiration on temporary lists
  3. Consider streams for large message queues
  4. Use LLEN to check size before operations

Blocking Operations

Use BLPOP/BRPOP for efficient queue consumption:
# Consumer blocks waiting for messages
redis> BLPOP queue:tasks 30
1) "queue:tasks"
2) "task1"
Blocking operations (BLPOP, BRPOP) hold a connection until data is available or timeout occurs. Use appropriate timeouts to prevent connection exhaustion.

Patterns

Reliable Queue

Implement a reliable queue with processing list:
# Move item from queue to processing
redis> RPOPLPUSH queue:tasks queue:processing
"task1"

# After processing, remove from processing list
redis> LREM queue:processing 1 "task1"
(integer) 1

# On failure, move back to queue
redis> RPOPLPUSH queue:processing queue:tasks
"task1"

Circular List

Use RPOPLPUSH with same list for circular iteration:
redis> RPUSH mylist "one" "two" "three"
(integer) 3
redis> RPOPLPUSH mylist mylist
"three"
redis> LRANGE mylist 0 -1
1) "three"
2) "one"
3) "two"

Timeline

Store time-ordered events:
redis> LPUSH timeline:global "event3 at $(date +%s)"
(integer) 1
redis> LPUSH timeline:global "event2 at $(date +%s)"
(integer) 2
redis> LPUSH timeline:global "event1 at $(date +%s)"
(integer) 3
redis> LRANGE timeline:global 0 9
1) "event1 at 1234567890"
2) "event2 at 1234567880"
3) "event3 at 1234567870"

List vs Other Data Structures

FeatureListStreamSorted Set
OrderInsertionTime-based IDScore-based
DuplicatesYesYesNo (unique members)
AccessIndex, RangeID, RangeScore, Rank
Use CaseQueues, StacksEvent streamsLeaderboards
BlockingYes (BLPOP)Yes (XREAD)No

Common Errors

  1. WRONGTYPE: Operating on wrong type
    redis> SET mykey "string"
    OK
    redis> LPUSH mykey "value"
    (error) WRONGTYPE Operation against a key holding the wrong kind of value
    
  2. Index out of range: LINDEX returns nil
    redis> LINDEX mylist 1000
    (nil)
    

Build docs developers (and LLMs) love