Theory / 10 min
Single-Node Key-Value Core
Redis begins with a deceptively small idea: keep a dictionary in memory, let clients mutate it with commands, and send replies as fast as the network allows.
That sentence is almost too simple. It makes Redis sound like a weekend project. Yet most of the system's power comes from refusing to lose the clarity of that idea as the server grows into persistence, replication, clustering, scripting, streams, eviction, and failover.
At the heart of a single Redis node is a path like this:
socket bytes -> parsed command -> command handler -> in-memory database -> reply bytes
The database is a keyspace: a mapping from key bytes to Redis objects. A client sends a command such as SET name Ada. The server parses the bytes, finds the SET handler, stores an object under the key name, and writes an OK reply. A later GET name travels the same path and returns the stored value.
The Keyspace Is The Center
It is tempting to describe Redis as a cache, but that undersells the design. A cache is one use case. Redis is better understood as an in-memory data structure server whose primary state is a shared keyspace.
Every connected client speaks to that same keyspace unless it explicitly selects a different logical database. Connections are not private stores. They are routes into shared memory.
In a tiny implementation, the database might look like this:
type RedisObject = {
type: "string";
value: Buffer;
};
type Database = Map<string, RedisObject>;
Even if the first version supports only strings, wrapping the value in an object is the right shape. Later, that object can represent a list, hash, set, sorted set, stream, or module-defined value. The command path does not need to be rediscovered every time a new data type appears.
Bytes, Not Just Strings
Redis keys and values are binary safe. The word "string" in Redis does not mean a Unicode string in the application-language sense. It means a sequence of bytes.
That distinction matters. The same storage path can hold "Ada", a serialized session, a compressed blob, or a counter represented as ASCII digits. Numeric commands such as INCR interpret a string value as an integer when needed, but the stored logical type remains a Redis string.
This byte-oriented model is one reason Redis feels both low-level and ergonomic. It does not impose a document schema, but it does provide high-level operations over carefully chosen data structures.
Commands Are Small Transactions Of Meaning
Each command should leave the database coherent before its reply is sent. SET creates or replaces a value. DEL removes keys. GET observes without mutating, except for related housekeeping such as discovering that an expired key should be treated as gone.
That command-level coherence is one reason Redis can execute commands in a single main thread for so much of its history. A command runs to completion, then the next command observes a valid state. Concurrency is handled around the command path through network multiplexing, not by letting arbitrary command handlers race against one another inside the keyspace.
A minimal handler keeps those boundaries visible:
function setCommand(db, args) {
const [key, value] = args;
db.set(key, { type: "string", value });
return "+OK\r\n";
}
function getCommand(db, args) {
const [key] = args;
const object = db.get(key);
if (!object) return "$-1\r\n";
return `$${object.value.length}\r\n${object.value}\r\n`;
}
Parsing is not in the handler. Socket writing is not in the handler. Persistence is not in the handler. The command's job is to express the semantic change or observation.
The Pattern That Keeps Returning
Once the single-node core is clear, Redis becomes much easier to learn. Expiration is metadata that decides when keys disappear. Eviction is policy that decides what to remove under memory pressure. Persistence records the keyspace or the writes that produced it. Replication copies the keyspace and streams future changes. Cluster mode assigns slices of the keyspace to different nodes.
The same little machine keeps reappearing:
command enters -> keyspace changes or is read -> reply leaves
Redis starts making sense when that machine is clear before everything production-grade is layered on top.
See what actually stuck.
Take the practice scenarios now.