Dragonfly

Beginner’s Redis Tutorial with Cheat Sheet and Quick Start Guide

Redis is an open-source, in-memory key-value data store, often used as a cache, message broker, or lightweight NoSQL database.

October 10, 2025

Guides Cover | Redis Beginner's Tutorial

What Is Redis?

Redis is an open-source, in-memory key-value data store, often used as a cache, message broker, or lightweight NoSQL database. It holds all its data in memory, enabling extremely fast read and write operations.

Unlike traditional relational databases, Redis is not intended for complex analytical queries but rather for rapid access to data (i.e., string, binary blob, or composite types like list) for high-throughput, low-latency workloads. Its speed has made it a foundational technology behind scalable web applications and microservices.

Modern use cases for Redis include caching frequently accessed data to reduce database load, session management for web applications, real-time analytics, leaderboards, and publish-subscribe systems.

Its support for various data structures such as strings, hashes, lists, sets, and sorted sets further widens its applicability. Redis' popularity also stems from its rich client library support for nearly every major programming language, making it easy to integrate into diverse technology stacks.


Is Redis Open Source?

Redis has historically been open source, released under the BSD license since its inception in 2009. However, the licensing model began to evolve starting in 2019, when Redis Labs (now Redis Ltd.) released certain Redis modules to a more restrictive source-available license to prevent cloud providers from offering them as services without contributing back.

In March 2024, Redis Ltd. took a further step by switching the Redis core engine license from BSD to a dual license model: the Redis Source Available License (RSALv2) and the Server Side Public License (SSPLv1). Then in May 2025, the license changed again and is now a tri-license with the ability to use Redis as open source again, under the AGPLv3 license. This latest change applies to versions starting with Redis 8 and onward.

To summarize, Redis 7.2 and earlier remain under the permissive BSD license and are still widely used in open-source applications, and Redis 8 onwards is also fully open source. However, the long-term status of Redis as a truly open-source project is now uncertain due to multiple policy shifts in recent years.


Core Redis Concepts 

Redis operates on a few key concepts that define its behavior and performance. Understanding these concepts is essential for effectively using Redis in various applications.

Key-Value Store

At its core, Redis is a key-value store. Data is stored as a collection of keys, where each key is associated with a value. Redis supports simple data types for the value, such as strings, but also more complex types like hashes, lists, sets, and sorted sets. This flexibility allows Redis to handle a wide range of use cases.

Starting with Redis 8.0, all existing RedisStack types and features are bundled in the Redis server by default—this includes JSON, search, time series, and probabilistic data structures. In addition, Redis 8.0 adds a new native data type, vector set. These additions create new suitable use cases for the Redis platform.

Data Structures

Redis is actually more than just a key-value store with the value being a simple string or binary blob. Instead, Redis provides a set of built-in data structures as well as corresponding commands to atomically operate directly on these data structures.

  • Strings: The most basic type, which holds a sequence of characters or binary data.
  • Hashes: Used for storing objects with multiple fields, like a user profile with fields like name, email, etc.
  • Lists: Ordered collections of elements that can be used to represent queues or logs.
  • Sets: Unordered collections of unique elements, useful for tasks such as deduplication.
  • Sorted Sets: Like sets but with an associated score for each element, allowing for ranking and sorting operations.
  • JSON: Allows storing and querying structured JSON documents using path-based access. Useful for representing nested data like API responses or user settings.
  • Vector Sets: Stores high-dimensional vectors for similarity search and AI workloads.

Persistence

While Redis is primarily an in-memory database, it also offers persistence options. Data can be saved periodically to disk (using snapshotting or append-only files), providing durability in exchange for reduced performance. Redis also supports replication, allowing for high availability and data redundancy.

Streaming and Messaging

Redis supports both pub/sub and streams for messaging. The pub/sub system allows publishers to send messages to channels, which are instantly delivered to all active subscribers. It's simple and fast but lacks durability; messages are lost if no subscribers are listening. In contrast, streams are more reliable and can be persisted, as they are part of the normal keyspace. They also support message IDs, consumer groups, and acknowledgments, making them suitable for building durable message queues, event logs, and data pipelines.

Atomic Operations

Redis has built-in atomic operations on its data structures. This means that individual operations like incrementing a value (i.e., INCR) or modifying a list (i.e., LPUSH) are performed as a single, indivisible action, ensuring consistency even in highly concurrent environments.

Transactions

Redis supports transactions through the MULTI, EXEC, and WATCH commands, enabling a series of commands to be executed as a single block without interference from other operations, improving data consistency.


Redis Commands Cheat Sheet

To effectively work with Redis, you should be familiar with the most commonly used commands. These commands allow you to interact with the Redis data store, perform operations on keys, and manipulate data structures.

SET and GET

SET is used to store a key-value pair in Redis, and GET retrieves the value associated with a given key:

redis$> SET session_token:123 "abcd1234pop"
redis$> GET session_token:123

This sets a key named session_token:123 with the value "abcd1234pop". Calling GET on that key returns the stored string.

DEL

DEL deletes one or more keys from the Redis database:

redis$> DEL session_token:123

This command will remove the key session_token:123 from the Redis store.

EXPIRE and TTL

The EXPIRE command sets a time-to-live (TTL) for a key, after which it will be automatically deleted. TTL checks the remaining time until a key expires. Note that the SET command also has additional options (i.e., EX) that can perform the set and expire operations atomically.

redis$> EXPIRE ser_token:123 60
redis$> TTL ser_token:123 
redis$> SET user_token:123 "abcd1234pop" EX 60

LPUSH and RPUSH

LPUSH and RPUSH add elements to the left or right of a list, respectively. These commands are useful for working with Redis lists.

redis$> LPUSH car_queue "Tesla Model S"
redis$> RPUSH car_queue "Ford Mustang"
redis$> LPUSH car_queue "BMW X5"
redis$> RPUSH car_queue "Audi A6"

You can fetch all the elements of the car_queue list using the following command:

redis$> LRANGE car_queue 0 -1

The output will be: 

1) "BMW X5"
2) "Tesla Model S"
3) "Ford Mustang"
4) "Audi A6"

SADD and SREM

SADD adds an element to a set, while SREM removes an element from a set. Redis sets are unordered collections of unique elements.

redis$> SADD baby_names "Emma"
redis$> SADD baby_names "Liam"
redis$> SADD baby_names "Olivia"
redis$> SADD baby_names "Noah"

Let's print the baby_names set using the following command:

redis$> SMEMBERS baby_names

The output will be:

1) "Olivia"
2) "Noah"
3) "Liam"
4) "Emma"

Now, let's remove "Noah" from the set:

redis$> SREM baby_names "Noah"

Let's print it again to check the members, and now the output becomes:

1) "Olivia"
2) "Liam"
3) "Emma"

HSET and HGET

HSET and HGET are used for manipulating the hash data type. HSET stores a field in a hash, and HGET retrieves the value of a field in the hash.

redis$> HSET airlines:500 name "Emirates" year_founded 1985
redis$> HSET airlines:501 name "Qatar Airways" year_founded 1992
redis$> HSET airlines:502 name "Singapore Airlines" year_founded 1947
redis$> HGET airlines:501 name
#=>"Qatar Airways"

ZADD and ZRANGE

ZADD adds elements to a sorted set, while ZRANGE retrieves elements from the sorted set by their rank, score, or lexicographical order.

redis$> ZADD sales_rank 35000 "agent_alice"
redis$> ZADD sales_rank 25000 "agent_bob"
redis$> ZADD sales_rank 15000 "agent_charlie"
redis$> ZRANGE sales_rank 0 1 REV WITHSCORES

The ZRANGE command above returns the top 2 elements based on rank, and the output will be:

1) "agent_alice"
2) "35000"
3) "agent_bob"
4) "25000"

Quick Start with Redis in Python 

In this tutorial, we will walk through the process of getting started with Redis using Python. We will cover the installation of the necessary libraries, setting up a Redis connection, and running some basic Redis commands in a Python environment. These instructions are adapted from the Redis documentation.

Step 1: Install Redis and redis-py

Before interacting with Redis from Python, you need to install the Redis server on your system and the redis-py library, which provides a Python interface to Redis. If you're using Docker, you can easily run Redis by executing the following command:

$> docker run -d --name redis-stack -p 6379:6379 -p 8001:8001 redis/redis-stack:latest

This will run Redis on your local machine and expose it on port 6379. Alternatively, you can install Redis natively by following the appropriate installation instructions for your operating system (Linux, macOS, or Windows). To interact with Redis from Python, you need to install the redis-py package. You can do this using pip:

$> pip install redis

Step 2: Connect to Redis from Python

Once Redis and redis-py are installed, you can connect to the Redis server. Here's how you can create a connection pool and a Redis client in Python:

import redis

# Create a connection pool to the Redis server.
pool = redis.ConnectionPool(host='localhost', port=6379, db=0)

# Create a Redis client using the connection pool.
r = redis.Redis(connection_pool=pool)

Step 3: Basic Redis Operations

Now that you are connected to Redis, you can perform basic operations such as setting and getting keys, deleting keys, checking for key existence, and more.

Set and Get Keys

You can set a key-value pair in Redis using the set() method, and retrieve the value with the get() method:

r.set('key', 'value')
value = r.get('key')
print(value)

Delete Keys

You can delete one or more keys from Redis using the delete() method:

r.delete('key')                   # Delete a single key.
r.delete('key1', 'key2', 'key3')  # Delete multiple keys.

Check If a Key Exists

To check if a key exists in the database, use the exists() method:

if r.exists('key'):
	print("Key exists!")
else:
	print("Key does not exist.")

Set Expiration on Keys

You can set an expiry time for a key using the expire() method:

r.expire('key', 30)  # Set key to expire in 30 seconds.

If you want to remove the expiry, use the persist() method:

r.persist('key')  # Remove expiry from the key.

Increment and Decrement Numbers

Redis supports atomic operations on numbers. You can increment or decrement a number stored in a key:

r.incr('counter')  # Increment the value of 'counter' by 1.
r.decr('counter')  # Decrement the value of 'counter' by 1.

Step 4: Running Redis Commands Directly

In addition to using redis-py methods, you can directly execute Redis commands using the execute_command method. For example:

r.execute_command('SET', 'new_key', 'new_value')  # Set a key using the Redis command syntax.

Step 5: Handling Errors

While interacting with Redis, it's essential to handle potential exceptions, such as network issues or Redis server failures. You can use Python's try and except blocks to catch and handle these errors:

try:
	r.set('key', 'value')  
	value = r.get('key')
except redis.RedisError as e:
	print(f'Redis error occurred: {e}')

By following this tutorial, you've set up Redis with Python, performed common Redis operations, and laid the groundwork for building high-performance applications with Redis.


Working with Redis Data Structures in Python

To work effectively with Redis in Python, it's important to understand how to manipulate core Redis data structures such as strings, lists, hashes, sets, and sorted sets. The redis-py client offers straightforward methods to interact with these types.

Strings

Strings are the most basic data type in Redis. You can store and retrieve string values using set() and get():

r.set("license_number", "12345")
value = r.get("license_number")

Lists

Lists are ordered collections of elements. You can push elements to either end and pop them as needed:

r.lpush("print_jobs", "job1")      # Add to list head.
r.rpush("print_jobs", "job2")      # Add to list tail.
print_jobs = r.lpop("print_jobs")  # Remove from list head.

Hashes

Hashes map fields to values, like Python dictionaries. They're useful for storing structured data:

r.hset("car:c001", "model", "Camry")
r.hset("car:c001", "manufacturer", "Toyota")
model = r.hget("car:c001", "model")

Sets

Sets hold unique, unordered values. You can add elements with sadd() and retrieve them with smembers():

r.sadd("tags:music", "jazz", "rock", "blues")
tags = r.smembers("tags:music")

Sorted sets

Sorted sets are like sets but with an associated score for each element. They are commonly used for ranking systems:

r.zadd("donations", {"john_doe": 150.0, "jane_smith": 300.0})
donors = r.zrange("donations", 0, -1, withscores=True)

By understanding these structures, Python developers can leverage Redis to implement features like queues, sessions, ranking systems, and real-time analytics.


Redis Best Practices for New Developers 

Here are some useful practices to consider when working with Redis.

1. Optimize Redis Data Structures

Choosing the right Redis data structure for your use case is crucial to maximizing performance. For example, lists can be suitable for queues but are less efficient for set-based operations. Instead of using a list to track unique items, use a set to avoid duplication. 

Likewise, when you need to store related data with unique keys, consider using hashes to group related fields rather than multiple keys. Always choose the smallest data structure that meets your needs to minimize memory consumption and improve query speed. For example, if you're storing a collection of unique IP addresses, use a set:

r.sadd('unique_ip_addresses', '192.168.1.1')

This operation is far more efficient than using a list, as sets are optimized for membership checks and prevent duplicates automatically.

2. Be Careful with Blocking Commands

Blocking commands, such as BLPOP, BRPOP, and BZPOPMIN, should be used cautiously, especially in a production environment where responsiveness is critical. These commands block the client until an element is available, which can slow down your application if overused or misconfigured. 

Instead, consider designing your application to use non-blocking alternatives or manage these operations with timeouts to avoid potential bottlenecks.  For example, if you're using BLPOP to wait for a download task in a queue, set a timeout so the worker doesn't block indefinitely if no tasks are available:

download_task = r.blpop('download_queue', timeout=5)  # Wait up to 5 seconds for a new download task.
if download_task is None:
    print("No download task available — continuing without blocking.")

This ensures that your workers can handle idle periods gracefully without blocking the rest of your system.

3. Use Redis Pipelining

Redis pipelining allows you to send multiple commands to the Redis server in a single batch, minimizing network round-trip time and improving throughput. This is especially useful when you need to perform many independent operations, like updating multiple counters, as it reduces the overhead of waiting for responses from the server.

For example, instead of sending commands individually:

r.incr('page_views:home')
r.incr('page_views:about')
r.incr('page_views:contact')

You can pipeline them like this:

with r.pipeline() as pipe:
	pipe.incr('page_views:home')
	pipe.incr('page_views:about')
	pipe.incr('page_views:contact')
pipe.execute()

This approach significantly reduces the time spent on waiting for responses between each command.

4. Use Redis' Lua Scripting for Atomic Operations

Redis supports Lua scripting, which allows you to execute a series of commands atomically. This ensures that a group of operations can be executed without interference from other clients. Lua scripts are particularly useful when you need to perform complex operations that involve multiple commands but require them to execute as a single, indivisible transaction.

For example, if you want to set a key with a value and an expiration only if it doesn't already exist (e.g., for a distributed lock):

script = """
if redis.call('exists', KEYS[1]) == 0 then
	redis.call('set', KEYS[1], ARGV[1])
	redis.call('expire', KEYS[1], tonumber(ARGV[2]))
	return 1
else
return 0
end
"""
result = r.eval(script, 1, 'lock:resource', 'locked', 30)

Note that to maximize efficiency, it's recommended to load the script to the Redis server (by using SCRIPT LOAD) and then use EVALSHA to execute the cached script.

5. Use Connection Pooling

Redis is designed for high-performance environments, and connection pooling can significantly improve efficiency by reusing existing Redis connections. Without pooling, each operation requires establishing a new connection, which adds latency and reduces throughput. Using a connection pool allows Redis clients to reuse existing connections, improving response times and minimizing resource consumption.

Here's how you can set up connection pooling in redis-py:

pool = redis.ConnectionPool(host='localhost', port=6379, db=0)
r = redis.Redis(connection_pool=pool)

Connection pooling is especially beneficial in multi-threaded or multi-process environments where multiple clients need to share Redis connections efficiently.

6. Monitor Redis Performance

Regular monitoring of Redis performance is crucial to ensure that it operates optimally and scales with your application's demands. Redis provides built-in commands like INFO and MONITOR to track key metrics such as memory usage, command processing time, and connections.

To get general statistics about Redis:

redis_stats = r.info()
print(redis_stats)

This will return a dictionary containing details like memory usage, keyspace hits/misses, and the number of connected clients. By monitoring these metrics, you can identify potential issues, such as memory pressure or slow command execution, and adjust your Redis configuration or usage patterns accordingly.

For real-time monitoring, you can use tools like RedisInsight or integrate Redis metrics with external monitoring systems like Prometheus to visualize the performance over time.


Dragonfly: Next-Gen In-Memory Data Store with Limitless Scalability

Dragonfly is a modern, source-available, multi-threaded, Redis-compatible in-memory data store that stands out by delivering unmatched performance and efficiency. Designed from the ground up to disrupt legacy technologies, Dragonfly redefines what an in-memory data store can achieve.

Dragonfly Scales Both Vertically and Horizontally

Dragonfly's architecture allows a single instance to fully utilize a modern multi-core server, handling up to millions of requests per second (RPS) and 1TB of in-memory data. This high vertical scalability often eliminates the need for clustering—unlike Redis, which typically requires a cluster even on a powerful single server (premature horizontal scaling). As a result, Dragonfly significantly reduces operational overhead while delivering superior performance.

For workloads that exceed even these limits, Dragonfly offers a horizontal scaling solution: Dragonfly Swarm. Swarm seamlessly extends Dragonfly's capabilities to handle 100 million+ RPS and 100 TB+ of memory capacity, providing a path for massive growth.

Key Advancements of Dragonfly

  • Multi-Threaded Architecture: Efficiently leverages modern multi-core processors to maximize throughput and minimize latency.
  • Unmatched Performance: Achieves 25x better performance than Redis, ensuring your applications run with extremely high throughput and consistent latency.
  • Cost Efficiency: Reduces hardware and operational costs without sacrificing performance, making it an ideal choice for budget-conscious enterprises.
  • Redis API Compatibility: Offers seamless integration with existing applications and frameworks running on Redis while overcoming its limitations.
  • Innovative Design: Built to scale vertically and horizontally, providing a robust solution for rapidly growing data needs.

Dragonfly Cloud

Dragonfly Cloud is a fully managed service from the creators of Dragonfly, handling all operations and delivering effortless scaling so you can focus on what matters without worrying about in-memory data infrastructure anymore.

Was this content helpful?

Help us improve by giving us your feedback.

Switch & save up to 80%

Dragonfly is fully compatible with the Redis ecosystem and requires no code changes to implement. Instantly experience up to a 25X boost in performance and 80% reduction in cost