LPUSH, RPUSH, and LPOP
Learn LPUSH, RPUSH, and LPOP in Redis with hands-on exercises. Master left/right push and left pop for list operations.
Focus: lpush, rpush, and lpop
Have you ever needed to manage a queue in Redis and didn't know whether to push left or right? Or worse, you tried to pop from the wrong end and got unexpected results? Mastering LPUSH, RPUSH, and LPOP is the key to building fast, predictable lists and queues in Redis — and this lesson clears up the confusion once and for all.
The problem this lesson solves
Redis lists are versatile, but without understanding the direction of operations, you risk building a queue that behaves backwards, or losing data because you popped the wrong element. Many developers use LPUSH and RPUSH interchangeably without realizing each command determines the order elements are stored. LPOP then reads and removes the first element. If you've ever had a list that felt "reversed" or couldn't trust your FIFO queue, this lesson fixes that by teaching you exactly how left, right, and pop work together.
Core concept / mental model
Think of a Redis list as a horizontal shelf with a left end and a right end. LPUSH adds an item to the left side — like putting a book on the leftmost spot, pushing everything else to the right. RPUSH adds to the right side, like placing a book on the rightmost spot. LPOP then takes the leftmost book off the shelf. This creates two natural patterns:
- Stack (LIFO): LPUSH + LPOP — last pushed is first popped.
- Queue (FIFO): RPUSH + LPOP — first pushed is first popped.
These three commands alone let you model any linear data structure you need.
How it works step by step
- Choose your direction: Decide if you want to push to the left or right based on your use case (stack vs queue).
- Execute the push: Run
LPUSH key valueorRPUSH key value. Both return the length of the list after insertion. - Pop from left: Run
LPOP keyto remove and return the leftmost element. If the list is empty, it returns(nil). - Monitor length: After each operation, the list length is returned, helping you track state.
Pro tip: To pop from the right instead, use
RPOP. But for this lesson, we stick withLPOPsince it pairs naturally with bothLPUSHandRPUSH.
Hands-on walkthrough
Let's open redis-cli and see these commands in action.
Example 1: Building a simple queue (FIFO)
# Add items to the right of the list "queue"
127.0.0.1:6379> RPUSH queue "first"
(integer) 1
127.0.0.1:6379> RPUSH queue "second"
(integer) 2
127.0.0.1:6379> RPUSH queue "third"
(integer) 3
# Pop from the left to process in order
127.0.0.1:6379> LPOP queue
"first"
127.0.0.1:6379> LPOP queue
"second"
127.0.0.1:6379> LPOP queue
"third"
127.0.0.1:6379> LPOP queue
(nil) # list is empty
Notice how RPUSH + LPOP gives you First-In-First-Out behavior. The first item pushed (first) is the first popped.
Example 2: Building a stack (LIFO)
# Add items to the left
127.0.0.1:6379> LPUSH stack "alpha"
(integer) 1
127.0.0.1:6379> LPUSH stack "beta"
(integer) 2
127.0.0.1:6379> LPUSH stack "gamma"
(integer) 3
# Pop from the left to get last pushed first
127.0.0.1:6379> LPOP stack
"gamma"
127.0.0.1:6379> LPOP stack
"beta"
127.0.0.1:6379> LPOP stack
"alpha"
LPUSH + LPOP creates a Last-In-First-Out stack: gamma was pushed last, popped first.
Example 3: Using Python with redis-py
import redis
r = redis.Redis(host='localhost', port=6379, decode_responses=True)
# Clear the list first
r.delete('tasks')
# Add tasks to the right (queue)
r.rpush('tasks', 'send email')
r.rpush('tasks', 'generate report')
r.rpush('tasks', 'backup database')
# Process tasks from the left
while r.llen('tasks') > 0:
task = r.lpop('tasks')
print(f"Processing: {task}")
Expected output:
Processing: send email
Processing: generate report
Processing: backup database
Example 4: Checking list contents
127.0.0.1:6379> RPUSH mylist "a" "b" "c"
(integer) 3
127.0.0.1:6379> LPUSH mylist "d"
(integer) 4
127.0.0.1:6379> LRANGE mylist 0 -1
1) "d"
2) "a"
3) "b"
4) "c"
Here LPUSH added d to the left, so it appears first in the range. RPUSH added a, b, c to the right in order.
Compare options / when to choose what
| Operation | Direction | Use case | Example pattern |
|---|---|---|---|
LPUSH + LPOP |
Left-Left | Stack (LIFO) | Undo history, recent actions |
RPUSH + LPOP |
Right-Left | Queue (FIFO) | Task queues, message pipelines |
RPUSH + RPOP |
Right-Right | Stack (LIFO) from other end | Less common, but symmetrical |
LPUSH + RPOP |
Left-Right | Queue (FIFO) reversed | Another valid queue pattern |
Pro tip: Most production queue systems use
RPUSH+LPOPbecause it keeps the natural order: older items are on the left, newer on the right.
- Choose
LPUSHwhen you want new items to be processed soon (stack behavior). - Choose
RPUSHwhen you want fair, first-come-first-served processing (queue behavior). - Always pair
LPOPwithRPUSHfor a classic queue, or withLPUSHfor a classic stack.
Troubleshooting & edge cases
Mistake 1: Mixing push directions unintentionally
127.0.0.1:6379> LPUSH list "x"
(integer) 1
127.0.0.1:6379> RPUSH list "y"
(integer) 2
127.0.0.1:6379> LPOP list
"x" # That's expected, but your order is now mixed
If you intended a strict queue, using both LPUSH and RPUSH will break the order. Stick to one direction per list.
Mistake 2: Popping from an empty list
127.0.0.1:6379> LPOP nonexistent
(nil)
This returns nil in Redis or None in Python. Always check llen before popping in a loop.
Mistake 3: Forgetting decode_responses=True in redis-py
Without it, you'll get bytes back:
r = redis.Redis() # no decode
result = r.lpop('mykey')
print(result) # b'value' instead of 'value'
Edge case: Very long lists
Redis lists can hold up to 4 billion elements, but popping from a list that large one element at a time is slow. Use BRPOP for blocking pops or LTRIM to keep the list bounded.
What you learned & what's next
You now understand the core idea behind LPUSH, RPUSH, and LPOP:
- LPUSH adds to the left side, RPUSH adds to the right, LPOP removes from the left.
- You can build stacks (LIFO) or queues (FIFO) by choosing the right pair.
- You completed a practical exercise using both redis-cli and Python.
What's next? In the next lesson, you'll explore LLEN and LRANGE to inspect and measure your Redis lists without modifying them — a crucial skill for debugging and monitoring queue length.
Practice recap
Open redis-cli and create a list called tasks. Use RPUSH to add five task names, then LPOP three times. Verify the order matches FIFO. Then try LPUSH with the same items and LPOP to see the stack behavior. Finally, use LRANGE to view the remaining items.
Common mistakes
- Mixing LPUSH and RPUSH on the same list, breaking queue order
- Popping from an empty list and not checking for nil (returns (nil) in CLI, None or empty bytes in Python)
- Forgetting decode_responses=True in redis-py, causing byte string results instead of plain strings
- Using LPUSH + LPOP for queues when you really want RPUSH + LPOP for FIFO behavior
Variations
- Use BRPOP instead of LPOP for blocking pop in worker queues (waits for new elements)
- Use LTRIM after LPUSH/RPUSH to keep lists bounded (e.g., keep only last 1000 items)
- Use RPOPLPUSH to move elements between lists atomically (e.g., for reliable queues)
Real-world use cases
- Job queue: RPUSH new jobs, LPOP to process them one at a time (FIFO)
- User activity log: LPUSH recent actions, LPOP to display last N in a stack (LIFO)
- Chat message buffer: RPUSH incoming messages, LPOP to broadcast in order
Key takeaways
- LPUSH adds to the left end of a list; RPUSH adds to the right
- LPOP removes and returns the first element from the left
- RPUSH + LPOP creates a FIFO queue (first in, first out)
- LPUSH + LPOP creates a LIFO stack (last in, first out)
- Always check list length before popping to avoid nil/None returns
Keep learning
Related tutorials, quizzes, and articles for this topic.
Discussion
Questions, corrections, and tips help everyone reading this page.
0 comments
Add a comment
No comments yet — start the thread.