100% Free Forever
AI-Powered Learning
Industry Expert Content
Certificates & Badges
Learn At Your Own Pace
Redis

Pipelining in Redis

How Redis pipelining collapses many network round trips into one for bulk operations, how it differs from MULTI/EXEC transactions, and when it can't help.

Performance & CachingIntermediate8 min readJul 10, 2026
Analogies

The Cost of Round Trips

Every Redis command a client sends normally waits for the server's response before the client sends the next one, and even though Redis itself might execute a GET in microseconds, the network round trip between client and server — say 0.5ms on a fast local network, more over the internet — dominates the total time when an application needs to issue hundreds or thousands of commands in a loop. Pipelining eliminates this wasted waiting by having the client write multiple commands to the socket back-to-back without waiting for each individual reply, then read all the responses together once the server has processed them in order, collapsing what would have been N round trips into effectively one.

🏏

Cricket analogy: It is like a fielding captain sending in five bowling-change instructions to the umpire all at once between overs instead of walking to the boundary rope and back separately for each individual instruction, saving the repeated walking time.

Pipelining in Practice

Most Redis client libraries expose pipelining as an explicit object — for example redis-py's r.pipeline() — that you fill with a sequence of queued commands and then flush with a single execute() call, which sends every queued command in one write and returns a list of results in the same order the commands were queued. This is especially valuable for bulk operations like warming a cache with thousands of keys after a deploy, or fetching a batch of related records where each one would otherwise be a separate GET, turning what might be several seconds of sequential round-trip latency into tens of milliseconds of pipelined execution.

🏏

Cricket analogy: It is like a scorer entering an entire over's worth of six deliveries into the digital scoring app in one batch update at the end of the over rather than submitting each ball's outcome as a separate save action.

python
import redis

r = redis.Redis(decode_responses=True)

# Without pipelining: 10,000 round trips
for i in range(10_000):
    r.set(f"warmup:key:{i}", "value")

# With pipelining: effectively one round trip
pipe = r.pipeline()
for i in range(10_000):
    pipe.set(f"warmup:key:{i}", "value")
results = pipe.execute()  # sends all commands, then reads all replies

Pipelining vs. Transactions (MULTI/EXEC)

It is a common misconception that pipelining provides atomicity — it does not: pipelining is purely a network optimization, and other clients' commands can still be interleaved with a pipeline's commands on the server between any two of them, since Redis processes each pipelined command as an independent operation as it arrives. True atomicity requires wrapping commands in MULTI and EXEC, which queues the commands and guarantees they execute as one uninterrupted block with no other client's commands running in between; in practice, redis-py's pipeline object supports an optional transaction=True mode that combines both benefits, pipelining the network writes while also wrapping them in MULTI/EXEC for atomicity.

🏏

Cricket analogy: It is like sending five separate scoring updates to the app quickly one after another versus locking the entire scoreboard so no other match's update can slip in between your five updates — speed alone doesn't guarantee nothing else touches the board in between.

Pipelining does not make commands atomic. If you need read-modify-write correctness across concurrent clients — for example, decrementing a stock count only if it's above zero — use MULTI/EXEC with WATCH for optimistic locking, or better yet, express the logic as a single Lua script via EVAL, which Redis always executes atomically regardless of pipelining.

When Pipelining Doesn't Help

Pipelining reduces round-trip overhead, but it does not reduce the actual CPU time Redis spends executing each command, so it offers little benefit for a handful of commands where round-trip latency was never the bottleneck, and it offers no benefit at all for commands whose results are needed before the next command can be constructed — for instance, you cannot pipeline 'GET the current counter value, then SET it to double that value' because the SET depends on knowing the GET's result, which isn't available until the pipeline is flushed and read back. In such dependent-command scenarios, either use a single command that does both atomically (like INCR or INCRBY), or fall back to a Lua script executed with EVAL so the entire read-then-write logic runs server-side in one round trip without needing the client to see an intermediate result.

🏏

Cricket analogy: It is like trying to decide the next ball's field placement before knowing whether the previous ball was hit for six or defended — the captain simply cannot pre-batch a field change that depends on information that doesn't exist yet.

  • Pipelining sends multiple commands to Redis without waiting for each individual reply, collapsing N round trips into effectively one.
  • It is a network-latency optimization, not a CPU-time optimization — Redis still executes each command individually.
  • Pipelining does not provide atomicity; other clients' commands can still interleave between pipelined commands on the server.
  • MULTI/EXEC provides true atomicity by queuing commands to run as one uninterrupted block.
  • redis-py's pipeline(transaction=True) combines both pipelining's speed and MULTI/EXEC's atomicity.
  • Pipelining cannot help when one command's input depends on a previous command's not-yet-known result within the same batch.
  • Use a single atomic command (like INCR) or a Lua script via EVAL for dependent read-then-write logic in one round trip.

Practice what you learned

Was this page helpful?

Topics covered

#Redis#RedisStudyNotes#Database#PipeliningInRedis#Pipelining#Cost#Round#Trips#StudyNotes#SkillVeris