Skip to content
All question banks

Databases

Redis Questions

A comprehensive guide covering Redis fundamentals, data types, persistence, performance, scaling, and advanced features.

100 of 100 questions

Redis Fundamentals10

Redis (Remote Dictionary Server) is an open-source, in-memory data structure store that can be used as a database, cache, message broker, and streaming engine. It supports various data structures such as strings, hashes, lists, sets, and sorted sets with range queries.

Redis is a high-performance NoSQL database primarily used for scenarios requiring sub-millisecond response times. It is used because it stores data in RAM rather than on disk, making it ideal for caching, real-time analytics, session management, and leaderboard applications.

An in-memory database is a type of database management system that primarily relies on main memory (RAM) for data storage, in contrast to traditional databases that store data on disk. This architecture provides significantly faster read and write operations by eliminating disk seek time.

While Redis is a popular caching choice, it is much more than that. It is a full-featured data structure server that provides persistence options (RDB and AOF), complex data types, publish/subscribe capabilities, Lua scripting, and geospatial support, allowing it to function as a primary database.

MySQL is a relational database that stores data on disk in rows and columns, optimized for complex queries and ACID compliance. Redis is a NoSQL, in-memory store optimized for speed and simplicity, using key-value pairs rather than structured tables and relationships.

Redis is often preferred over Memcached because it supports more data types (lists, sets, hashes), offers built-in persistence, provides replication for high availability, and supports advanced features like transactions, Pub/Sub, and Lua scripting, whereas Memcached is purely a simple string-based cache.

Use Redis when you need the absolute lowest latency possible for simple data structures or real-time processing. MongoDB is better suited for storing large volumes of complex, nested JSON documents where disk-based storage and sophisticated querying or indexing are required.

Using Redis over local application memory (like a HashMap) allows the data to be shared across multiple server instances. It also provides features like automatic data expiration, persistence to disk, and atomic operations that are difficult to implement manually in application code.

Common Redis 'gotchas' include blocking the single-threaded event loop with slow commands (like KEYS *), running out of memory without a proper eviction policy, and data loss if persistence isn't configured correctly during a sudden system crash or reboot.

Redis is inappropriate for storing massive datasets that exceed the available RAM capacity of the server cluster. It is also not ideal for applications requiring complex relational queries, multi-table joins, or strict ACID compliance for every individual transaction across large datasets.

Redis Data Types20

Redis supports Strings (caching), Lists (message queues), Sets (unique member tracking), Hashes (storing objects/profiles), and Sorted Sets (leaderboards). Each type is optimized for specific computational complexity, allowing developers to choose the most efficient structure for their logic.

The Redis String is the most basic data type, capable of storing any kind of data, including binary data, up to 512 megabytes. They are commonly used for simple key-value caching of HTML pages, images, or session information.

SET is used to assign a string value to a specific key in the database, overwriting any existing value. GET is used to retrieve the value associated with that key; if the key does not exist, it returns a nil value.

Redis Lists are simply collections of strings sorted by insertion order. They are implemented as linked lists, which means that adding or removing elements from the head or tail of the list is performed in constant O(1) time.

Redis Lists are ideal for implementing message queues, where producers push items to the list and consumers pop them off. They are also useful for social media feeds or 'recent items' lists where only the latest entries are relevant.

Primary operations include LPUSH and RPUSH to add elements to the left or right side, and LPOP and RPOP to remove elements. LLEN retrieves the list length, while LRANGE allows you to fetch a specific range of elements.

Blocking operations like BLPOP and BRPOP allow a client to wait for elements to be pushed into a list if it is currently empty. The connection remains 'blocked' for a specified timeout, making it a highly efficient way to implement consumer polling.

A Redis Set is an unordered collection of unique strings. Unlike Lists, Sets do not allow duplicate elements. They are useful for tracking unique items like visitor IPs for a specific day or members of a particular group.

Sets should be used when you need to store unique items and perform set-based logic, such as finding common friends between two users, tracking unique tags for a blog post, or checking if an item exists in a large collection.

Standard operations include SADD to add members, SREM to remove them, and SISMEMBER to check if a value exists. Scard provides the count of elements, and SMEMBERS returns all the strings currently stored in the set.

SINTER computes the intersection of multiple sets, returning members that appear in every set. SUNION computes the union, returning all members present in at least one of the provided sets, effectively merging them while maintaining uniqueness.

These commands perform the same logic as SUNION and SINTER but instead of returning the result to the client, they store the resulting set into a new destination key, which is useful for caching complex set calculations.

Redis Hashes are maps between string fields and string values, making them the perfect data type to represent objects like a 'User' with fields for name, email, and password. They are extremely memory-efficient for small objects.

They are essentially dictionaries stored within a Redis key. This allows you to group related data together under a single identifier, preventing the 'namespace pollution' that would occur if every field were its own top-level Redis key.

Hashes are best used to store application objects where you need to frequently access or modify individual fields without having to serialize and deserialize a whole JSON string from a standard Redis String key.

Operations include HSET to set a field value, HGET to retrieve it, and HDEL to remove a field. HGETALL returns all fields and values, while HINCRBY can be used to increment a numeric field value atomically.

Sorted Sets are similar to Sets but every member is associated with a numeric score. Elements are kept sorted by their scores, allowing for extremely fast retrieval of top or bottom items within a specific range.

The most common use case is a gaming leaderboard. You store the player ID as the member and their score as the sorted set score. Redis then automatically keeps the ranking up-to-date, allowing you to fetch the top 10 players instantly.

ZADD adds or updates a member's score, ZREM removes a member, and ZRANK finds the position of a member. ZRANGE allows fetching members by index range, and ZREVRANGE fetches them in reverse order (highest scores first).

Redis uses various internal structures depending on the data size, including SDS (Simple Dynamic Strings), linked lists, zip lists (memory optimized), skip lists (for sorted sets), and hash tables to ensure O(1) or O(log N) performance.

Keys & Memory Management6

Keys in Redis are binary-safe strings, meaning you can use anything from a simple word to the content of a JPEG file as a key. Best practice dictates using colon-separated namespaces like 'user:1001:profile' to keep the keyspace organized.

Redis does not provide a direct O(1) command to check for a specific value inside a List. You would typically need to iterate with LPOS or maintain a companion Set alongside the List to perform existence checks in constant time.

Key eviction is the process where Redis removes old data to make room for new data when the memory limit is reached. It is configured via the 'maxmemory-policy' setting, with options like LRU (Least Recently Used) or LFU (Least Frequently Used).

Redis allocates memory primarily using jemalloc and tracks usage internally. It optimizes storage by using compressed structures for small datasets and allows users to set a 'maxmemory' limit to prevent the system from exhausting the host's physical RAM.

If the 'maxmemory' limit is hit, Redis will either return errors for write commands (under the 'noeviction' policy) or begin deleting keys according to the configured eviction policy (like 'allkeys-lru') to free up space for new data.

A single key or value is limited to 512MB. Additionally, while Redis can handle billions of keys, performance may degrade if memory fragmentation becomes high or if a single large data structure (like a hash with millions of fields) is used improperly.

Persistence & Durability12

Yes, Redis provides multiple options for data persistence. While it is an in-memory database by default, you can configure it to save snapshots to disk or log every write operation to ensure data can be recovered after a restart.

Persistence is ensured by enabling RDB (Redis Database) snapshots, which save the dataset at specific intervals, or AOF (Append Only File), which records every write command received by the server to a persistent log file.

By default, without persistence enabled, data is lost on a crash. However, if AOF is configured with 'fsync always' or 'fsync everysec', the most recent data is safely written to disk, allowing Redis to rebuild the state upon reboot.

Redis creates a point-in-time snapshot of the dataset by forking a child process. The child process writes the entire dataset to a compact RDB file on disk while the parent process continues to serve client requests normally.

RDB (Redis Database) persistence performs point-in-time snapshots of your dataset at specified intervals. It is excellent for backups and disaster recovery as the resulting file is very compact, but you might lose data since the last snapshot was taken.

AOF persistence logs every write operation received by the server. When Redis restarts, it 'replays' these logs to reconstruct the original dataset. This provides much better durability than RDB because it can be configured to sync every second.

AOF (Append Only File) is a persistence mode that appends every write command to a file. It is more durable than RDB because it minimizes data loss, but the resulting files are typically larger and can take longer to load during startup.

Redis solves this using 'AOF Rewrite'. It creates a new AOF file in the background by reading the current state of the database and writing the shortest sequence of commands needed to recreate it, effectively shrinking the log size.

RDB is a compact binary snapshot optimized for fast restarts and backups, but prone to data loss between saves. AOF is a human-readable log of all writes providing higher durability but resulting in larger files and slower recovery times.

The general recommendation is to use both simultaneously. RDB provides a great way to handle backups and fast restarts, while AOF ensures that you don't lose more than a second of data in the event of a failure.

RDB has minimal impact on performance as it uses a background fork. AOF can impact performance depending on the 'fsync' policy; 'fsync always' is very safe but slow, while 'fsync everysec' provides a good balance between safety and speed.

Redis can be durable if AOF is configured with 'fsync always', but this significantly reduces performance. By default, most Redis users accept a small risk of data loss (1 second with fsync everysec) in exchange for massive throughput.

Transactions & Concurrency5

Redis transactions allow the execution of a group of commands in a single step. They are wrapped in MULTI and EXEC blocks, ensuring that all commands are serialized and executed sequentially without any other client's command interrupting them.

Yes, Redis supports transactions via the MULTI, EXEC, DISCARD, and WATCH commands. These provide 'all-or-nothing' execution for the command block, though they do not support traditional relational rollbacks if a command fails during execution.

Redis avoids rollbacks to maintain simplicity and high performance. Since Redis commands only fail if there is a syntax error or a type mismatch (which are usually programming bugs), the developers decided that rollbacks were not worth the performance overhead.

Redis core is single-threaded for command execution, which simplifies concurrency management because commands are executed one at a time. Multi-threaded applications can safely use Redis because the atomic nature of commands prevents data races at the database level.

Since the event loop is single-threaded, Redis handles concurrent requests by queuing them and executing them one by one. This ensures that a single data structure update is always atomic and cannot be interrupted by another operation.

Pipelining & Performance7

Pipelining is a technique where a client sends multiple commands to the server without waiting for the replies, then reads all replies in a single step. Use it when you need to perform many operations to reduce network Round Trip Time (RTT).

Pipelining is used to dramatically increase throughput when executing large batches of commands. By grouping commands together, you minimize the number of times the network stack and kernel must be invoked, which is often the primary bottleneck in Redis performance.

Transactions (MULTI/EXEC) ensure atomicity and isolation, preventing other clients from interfering with the block of commands. Pipelining is strictly a network optimization tool to send many commands at once and does not guarantee atomicity from other clients.

To utilize multiple CPU cores, you should run multiple Redis instances on the same physical machine using different ports and manage them as a Cluster or Sharded setup. Newer Redis versions also use multiple threads for certain background I/O tasks.

Redis is rarely CPU bound because the commands are simple; it usually reaches bottlenecks in memory bandwidth or network I/O. It becomes CPU bound only when performing complex operations like Lua scripts or heavy Sorted Set intersections.

Optimization for high read volume is achieved by setting up Redis Replication. You can have one primary instance for writes and multiple read-only replicas to distribute the read load, effectively scaling out your infrastructure.

Redis is typically 10 to 100 times faster than MongoDB for simple key-value operations because it resides entirely in memory and has no overhead for complex query parsing or disk-based storage management required by MongoDB.

Pub/Sub (Publish/Subscribe)3

Pub/Sub is a messaging pattern where senders (publishers) send messages to channels without knowing who the receivers are. Receivers (subscribers) express interest in one or more channels and only receive messages that are of interest.

Clients use the SUBSCRIBE command to listen to a channel. When another client uses the PUBLISH command on that same channel, Redis instantly pushes the message to all subscribed clients. Messages are 'fire-and-forget' and are not stored.

Common use cases include real-time chat applications, notifications systems, and internal microservices communication where components need to react to events asynchronously without requiring the persistence of those messages in a database.

Scaling & High Availability7

Redis can be scaled vertically by increasing the server's RAM and CPU, or horizontally through Sharding (partitioning data across multiple instances) or Redis Cluster, which provides automated sharding and high availability through master-slave replication.

Redis Cluster provides a way to run a Redis installation where data is automatically sharded across multiple nodes. It is important because it allows the dataset to grow beyond a single server's memory and provides automatic failover if a node crashes.

Replication copies the exact same data to multiple servers to provide high availability and read scaling. Sharding splits the dataset into smaller parts and distributes them across different servers to increase the total storage capacity and write throughput.

Redis Sentinel is a system designed to manage Redis instances. It performs three main tasks: Monitoring the health of masters and replicas, Notifications via an API, and Automatic Failover to promote a replica to master if the master fails.

Sentinel is primarily used to achieve high availability for non-clustered Redis setups. It acts as a guardian that monitors instances and automatically reconfigures the environment during failures, ensuring the application remains connected to a working primary node.

Redis Cluster is a distributed implementation of Redis that provides data sharding, replication, and failover. It uses 16,384 hash slots to determine which node stores a particular key, allowing for horizontal scaling to hundreds of nodes.

Replication works by a replica connecting to a master and receiving a full snapshot of the data (RDB file). After the initial sync, the master sends a stream of write commands to the replica to keep it updated in near real-time.

Caching Strategies4

In a distributed environment, you use a centralized Redis cluster accessible by all application instances. This ensures all servers see a consistent cache state and avoids the synchronization issues inherent in local, per-server memory caches.

Common patterns include Cache-Aside (app checks cache, then DB), Write-Through (app writes to cache and DB simultaneously), and Write-Behind (app writes to cache, cache updates DB later). Each has different trade-offs regarding consistency and performance.

Cache invalidation is the process of removing stale data from the cache. In Redis, this is handled by setting TTL (Time To Live) on keys, using the DEL command when data changes in the DB, or using Pub/Sub to notify app instances to clear their local state.

In Cache-Aside, the application is responsible for populating the cache after a miss. In Write-Through, the cache layer or application always updates the cache first whenever a database write occurs, ensuring the cache is never empty but increasing write latency.

Advanced Features6

Redis allows users to upload and execute Lua scripts on the server. This is powerful because scripts run atomically, allowing you to perform complex logic involving multiple keys and conditional checks without the network overhead of multiple round trips.

Redis Modules are dynamic libraries that can be loaded into Redis at runtime to add new data types and commands. They allow Redis to be extended with specialized capabilities like Graph processing, Machine Learning, or full-text search.

While you can store JSON as a serialized string in a Redis String key, it is more efficient to use the RedisJSON module. This allows you to store, query, and modify specific sub-elements of the JSON document without transferring the entire string.

RedisJSON is a module that implements JSON as a first-class data type in Redis. It provides commands to selectively update keys, append values to arrays, and perform fast searches within JSON documents using JSONPath syntax.

RedisGraph is a module that uses a sparse adjacency matrix representation to store and query graph data. It supports the Cypher query language, allowing for extremely fast relationship mapping and path-finding operations compared to traditional relational databases.

RedisSearch is a powerful indexing and full-text search engine module. It allows you to create indexes on your Redis data and perform complex queries, including geo-filtering, numeric range filtering, and boolean logic, with high performance.

Monitoring & Debugging5

Performance issues are monitored using the INFO command for system stats, the SLOWLOG to find high-latency queries, and external tools like Prometheus and Grafana. The MONITOR command can also be used to see every command processed in real-time.

Key monitoring commands include INFO (general stats), SLOWLOG (identifying slow operations), LATENCY DOCTOR (troubleshooting latency), and CLIENT LIST (viewing active connections). Using these commands helps maintain a healthy and responsive Redis environment.

The INFO command returns a vast amount of information and statistics about the Redis server in a format that is easy to parse. It covers memory usage, connected clients, replication status, CPU consumption, and keyspace statistics.

MONITOR is a debugging command that streams back every command processed by the Redis server. It is very useful for seeing what an application is doing, but it has a significant performance cost and should not be used in production.

Slow queries are identified using the 'SLOWLOG GET' command. You can configure the execution time threshold (in microseconds) using 'slowlog-log-slower-than', and Redis will record any command that takes longer than that to complete.

Security4

Redis offers basic password authentication, the ability to rename or disable dangerous commands, Access Control Lists (ACLs) for granular user permissions, and support for TLS/SSL to encrypt data transmitted between the client and the server.

To secure Redis, you should always set a strong password, use ACLs to restrict user actions, enable TLS for encryption, and most importantly, ensure that Redis is only accessible via a private network or protected by a firewall.

Yes, Redis supports authentication through the AUTH command. In older versions, this was a single global password, but modern Redis versions (6.0+) support multiple users with different passwords and permissions via the ACL system.

Redis ACL is a security feature that allows you to define multiple users with specific permissions. You can control which commands a user can run and which keys they can access, providing much better security than a single password.

Commands & Operations6

The EXPIRE command sets a timeout on a key, after which the key will be automatically deleted from the database. This is a fundamental feature for implementing caches where data should only be valid for a specific period.

The TTL (Time To Live) command returns the remaining time that a key has before it expires, measured in seconds. If the key has no associated expiration, it returns -1; if the key does not exist, it returns -2.

The DEL command is used to remove a specified key and its associated value from the Redis database. It is a fundamental operation that returns 1 if the key was removed and 0 if the key did not exist.

The EXISTS command is used to check if a specific key exists in the database. It returns 1 if the key exists and 0 if it does not, providing a fast way to verify data presence without retrieving the value.

SCAN is a cursor-based iterator that retrieves keys in small batches. It is superior to the KEYS command because KEYS blocks the entire server while searching, whereas SCAN allows for incremental iteration without impacting server responsiveness.

FLUSHDB deletes all keys from the currently selected database. FLUSHALL is more destructive, as it removes all keys from every single database on the Redis server simultaneously. Both should be used with extreme caution in production.

Use Cases & Best Practices5

Redis is commonly used for caching database results, managing user sessions, implementing real-time leaderboards, building message queues with Pub/Sub or Lists, rate limiting API requests, and storing geospatial data for proximity-based searches.

You might use Redis as a primary database for applications that require extreme performance and can tolerate the memory-first storage model, such as real-time gaming state, live sports analytics, or temporary high-speed data processing pipelines.

Rate limiting is typically implemented by creating a Redis key for each user or IP with an expiration. Each request increments the value using INCR; if the value exceeds the allowed threshold, further requests are rejected until the key expires.

Session management involves storing a unique session ID as a Redis key (typically a Hash or String) with a TTL. The application retrieves the user data from Redis on every request, providing fast, centralized session storage for distributed architectures.

Leaderboards are implemented using the Sorted Set (ZSET) data type. Player scores are stored as the ZSET 'score' and player IDs as 'members'. Redis automatically sorts the data, allowing you to fetch rankings and top scorers in logarithmic time.

Related