
Mastering Redis goes beyond simple caching. Dive deep into the 10 most essential Redis commands, their Big O time complexities, underlying C data structures, and how to execute them live in your browser using our WebAssembly Redis Simulator.
Redis (Remote Dictionary Server) is the undisputed king of in-memory caching. From massive enterprise architectures at Twitter and GitHub to lean indie-hacker startups, Redis is the glue that keeps high-traffic applications from buckling under database load. However, the vast majority of backend developers critically underutilize Redis. They treat it merely as a glorified memcached—setting string values and expiring them.
This is a massive missed opportunity. Redis is not a cache; it is a Data Structures Server. Underneath its deceptively simple CLI interface lies a highly optimized C codebase that implements wildly powerful structures like Skip Lists, HyperLogLogs, and Geo-Spatial indices.
In this extensive engineering guide, we will strip away the magic. We will explore the absolute core 10 commands that every backend developer must master. We will dissect their Big O time complexities, analyze their internal memory representations (from ziplists to raw hash tables), and discuss exactly when to use them in production systems. And the best part? You do not need to install Docker or mess with Homebrew to test these commands. You can execute every single command featured in this article using the MojoDocs Local-First WebAssembly Redis Engine right now.
The Architectural Context: Why Command Choice Matters
Before diving into the commands themselves, we must establish why choosing the correct Redis command is of life-or-death importance for your backend architecture.
Redis is fundamentally single-threaded (ignoring I/O threads introduced in Redis 6+). There is only one main event loop processing commands. This means that if you execute a command that takes 5 seconds to complete, every other client connection to your Redis server will be physically blocked and placed in a queue for 5 seconds. In a distributed microservices environment, a blocked Redis instance immediately cascades into database connection pooling exhaustion, leading to a catastrophic 502 Bad Gateway across your entire application stack.
Therefore, we must rigorously analyze the Time Complexity of every command. A command operating in O(1) executes in constant time. A command operating in O(N) scales linearly.
| Data Structure | Best Use Case | Read Time | Write Time |
|---|---|---|---|
| Strings | Session Tokens, HTML Caching | O(1) | O(1) |
| Hashes | JSON Objects, Metadata | O(1) | O(1) per field |
| Lists | Job Queues, Activity Feeds | O(N) if indexed | O(1) Push/Pop |
| Sorted Sets | Leaderboards, Rate Limiting | O(log(N)) | O(log(N)) |
SET and GET: The Foundation
Let's begin with the absolute basics, but examine them through a production-grade lens.
SET: Writing Data
The SET command is the atomic building block of Redis. It stores a string value against a string key. However, modern Redis merged several older commands (like SETEX and SETNX) into the core SET command via arguments.
SET user:1001:session "ey1234..." EX 3600 NX
- EX 3600: Automatically expires the key in 3600 seconds (1 hour). This is critical for session tokens or temporary rate limiting to prevent out-of-memory (OOM) crashes.
- NX: "Not eXists." This argument ensures the key is only set if it does not already exist. This is the foundation of distributed locking mechanisms.
Time Complexity: O(1). Setting a key takes mere microseconds because Redis internally uses a massive, pre-allocated hash table to resolve keys instantly.
GET: Retrieving Data
The counter-operation, retrieving the string data.
GET user:1001:session
Time Complexity: O(1). Reading a string is instantaneous. But beware of enormous strings. Redis allows strings up to 512MB in size. Executing a GET on a 200MB JSON string will block the main thread while the network interface attempts to transmit that enormous payload over the TCP socket.
HSET and HGETALL: Mastering Hashes
Storing massive JSON blobs as Strings is a common anti-pattern. If you have a user object with 50 fields, and you only want to update their "last_login" timestamp, using a String requires you to GET the massive JSON, parse it in your application, update the field, stringify it, and SET the massive JSON back. This is slow and prone to race conditions.
Instead, use Hashes.
HSET: Setting Hash Fields
HSET user:1001 username "john_doe" role "admin" last_login "1710982300"
Redis Hashes are maps between string fields and string values, perfect for representing objects. Internally, if the hash is small, Redis uses a highly memory-optimized ziplist. When it grows larger, it converts it into a full generic hash table.
Time Complexity: O(N) where N is the number of fields being set. For a single field update, it is effectively O(1).
HGETALL: Retrieving the Entire Object
HGETALL user:1001
This returns every field-value pair inside the hash. However, if the hash has 10,000 fields, HGETALL becomes dangerously slow. In production, prefer fetching specific fields using HMGET or paginating through the hash using HSCAN.
LPUSH and RPOP: The Queue Builders
Redis Lists are incredibly fast linked lists. Because they are linked lists (and not arrays), adding an element to the head or the tail of the list is a guaranteed constant-time operation. This makes Redis the ultimate lightning-fast message broker and background job queue.
LPUSH: Adding to the Queue
LPUSH system_logs "Error in module X"
This pushes a new element to the Left (the head) of the list. If the list does not exist, Redis safely creates it.
Time Complexity: O(1) for each element added.
RPOP: Consuming the Queue
RPOP system_logs
This removes and returns the element at the Right (the tail) of the list. By combining LPUSH (adding to the start) and RPOP (taking from the end), you have just implemented a robust FIFO (First In, First Out) queue architecture in two commands.
SADD and SISMEMBER: Unique Set Operations
When you need to ensure data uniqueness without risking duplicate entries, Redis Sets are your best friend. A Set is an unordered collection of unique strings.
SADD: Adding Unique Entities
Scenario A: The Social Media "Like" Button
Imagine building an app where you need to track the User IDs of everyone who liked a photo. Instead of a slow SQL INSERT that allows duplicates, you use a Redis Set.
SADD photo:998:likes 1001 1002 1005
If user 1001 tries to like the photo again, SADD will simply return an integer 0, ignoring the duplicate entry automatically without throwing an error.
Time Complexity: O(N) where N is the number of elements being added. (Effectively O(1) per element).
SISMEMBER: Fast Lookup Checks
When generating the HTML for the photo, you need to display a filled heart icon if the current user has already liked it. You do not query your slow PostgreSQL database for this.
SISMEMBER photo:998:likes 1001
Time Complexity: O(1). Redis calculates the hash function of the string and instantly knows if the element exists in memory, making it the fastest possible existence check.
ZADD and ZREVRANGE: The Leaderboard Engine
This is where Redis ascends into black magic. Sorted Sets are arguably the most powerful data structure in the Redis arsenal. They act like a regular Set, but every piece of data is associated with a floating-point number known as a Score. Redis automatically keeps the set structurally sorted by this score at all times using an advanced C data structure known as a Skip List combined with a hash table.
ZADD: Updating the Leaderboard
Scenario B: The Global Gaming Leaderboard
Let's build a global gaming leaderboard where scores update in real-time millions of times a minute. Traditional databases would lock tables to sort them.
ZADD global_highscores 15000 "player_one" 22000 "player_two"
If "player_one" plays again and their score increases to 18000, calling ZADD again will instantly update their score and reposition them in the sorted Skip List without duplicating their name.
Time Complexity: O(log(N)) for each item added. This logarithmic complexity allows Redis to maintain heavily sorted leaderboards of millions of players with near-zero latency.
ZREVRANGE: Fetching the Top 10
ZREVRANGE global_highscores 0 9 WITHSCORES
This command instantly returns the top 10 highest-scoring players along with their exact scores. Generating this data in a relational SQL database using massive ORDER BY score DESC LIMIT 10 queries on 50 million rows would fry your processor. In Redis, it takes less than 2 milliseconds.
The Most Dangerous Command: SCAN vs KEYS
We conclude with a warning. When a junior developer wants to find all keys matching a specific pattern, they often read a deprecated Stack Overflow post and execute:
KEYS session:*
CRITICAL WARNING: The KEYS Command
Never use the KEYS command in a production environment.
The command operates in strictly O(N) time where N is the total number of keys in your entire database. It must iterate linearly through millions of hash table slots to find matches. During this entire iteration—which could take several entire seconds—the single-threaded event loop is completely blocked, creating a fatal bottleneck. Your entire microservice architecture will go down with a 502 Bad Gateway.
SCAN: The Production Safe Alternative
To solve this, Redis introduced SCAN. It is a cursor-based iterator. It returns a small subset of matching keys and a cursor ID. You then pass that cursor back into the next SCAN call, pagination style.
SCAN 0 MATCH session:* COUNT 100
Because SCAN pauses its iteration, returns the payload, and relinquishes control of the main thread, other clients can execute their commands undisturbed. It operates in O(1) per call, ensuring your architecture remains asynchronous and alive.
Conclusion: Practice Without Penalty
Reading about these 10 commands is insufficient; you must build muscle memory. Normally, this means installing Redis via Docker, configuring ports, dealing with system path variables, and fighting the terminal.
We engineered a better way. The MojoDocs WebAssembly Redis Engine provides a fully functional, local-first Redis CLI directly in your browser. Every command discussed in this article (from complex Sorted Set operations to Hashes) runs inside the sandbox memory of your tab with absolute zero-latency.
Initialize Your Redis Engine
Test the 10 commands risk-free right now. No sign-ups, no server spin-ups. Just pure WebAssembly speed.
Launch the Redis Sandbox
