Redis Optimizing round-trip times with Pipelining

Ali Mohammad
4 min readApr 28, 2023

🥰 This short article will explain TCP, Request/Response Protocol, RTT, and Redis Pipelining.

🧐 Before we begin, let’s go over some of the terminology I use:

makeameme.org Terminology meme

TCP

TCP is a connection-oriented protocol, which means that it connects the sender and receiver before sending data. This connection is maintained throughout the duration of the transmission and ensures that the data is delivered in the correct order and without errors. TCP also controls the flow of data and checks for errors, which helps make sure the transmission is reliable.

Request/Response Protocol

In a request-response protocol, a client sends a request to the server, and the server responds with a response. People often call this process a “round-trip” because the client sends a request and the server sends a response back to the client. Usually, the TCP (Transmission Control Protocol) or the UDP (User Datagram Protocol) is used to set them up.

In a request-response protocol, the client sends a request to the server to start a conversation. The request may include data or parameters that the server needs to handle the request. The server processes the request and sends a response back to the client. Depending on the type of request and the result of the processing, the response could be data, an acknowledgement, or an error message.

RTT

Round-trip time, or RTT, is a measure of the time it takes for a client to send a request to the server and receive a response back. RTT is usually measured in milliseconds (ms), and it depends on things like how far away the client is from the server, how fast the network connection is, and how busy the server is.

💎 Pipelining

Pipelining means that the client can send multiple requests to the server without waiting for responses and then read the responses in a single step. Pipelining allows a client to send multiple requests to a server without waiting for responses and then read the responses all at once.

🥳 A real world code example

The following benchmark will use the Redis Ruby client, which supports pipelining, to test the speed improvement due to pipelining, as well as the benchmark gem.

Let’s go to our work directory and then type in your terminal:

gem install redis benchmark

Then, let’s start our redis server

brew services start redis

Once that is done, let’s head to our favorite IDE; mine is RubyMine; create a file called benchmarking_pipes.rb, and start coding:

require 'redis'
require 'benchmark'
# Connect to the Redis server
r = Redis.new
# Set the keys we'll be using for the benchmark
keys = ['food', 'ats', 'loush']
# With pipeline
puts Benchmark.measure {
# Start the pipeline
r.pipelined do
keys.each do |key|
5_000.times do
r.ping
r.incr(key)
r.get(key)
end
end
end
}
# Without pipeline
puts Benchmark.measure {
keys.each do |key|
5_000.times do
r.ping
r.incr(key)
r.get(key)
end
end
}

Let’s now run the script and witness the power of the pipeline!

ruby benchmarking_pipes.rb

Fabulous Right ?

Fa. Bu. Lous GIF

Use it with batches, and you’ve got fantastically optimized performance 😎

Advantages of Redis pipelining:

  • Improved performance: One of the main advantages of pipelining is that it can significantly improve the performance of Redis-powered applications. By reducing the number of network round-trips needed to execute commands, pipelining can significantly reduce the overhead of individual requests and improve the overall performance of the application.
  • Reduced latency: Pipelining can also help to reduce the latency of requests by allowing the client to send multiple commands in a single request. This can be especially useful for applications that rely on real-time data or have strict latency requirements.

Disadvantages of Redis pipelining:

  • No guarantees on command execution order: One potential drawback of pipelining is that it does not guarantee the order in which the commands are executed. This means that if you need to update multiple keys in a specific order, pipelining may not be the right choice. In these cases, the BATCH command can be used instead, which guarantees that the commands will be executed in the order they were sent.
  • Potential for increased complexity: Using pipelining can also increase the complexity of your code, as you’ll need to manage the pipeline and ensure that it is properly closed or reset when needed. This can be especially important when working with multiple threads or concurrent requests.

Hope you found this article interesting and useful ❤️

--

--