Redis (also known as Valkey in the community fork) is an in-memory data structure store that functions as a database, cache, message broker, and streaming engine. The entire dataset resides in RAM, enabling sub-millisecond latency for most operations. This architecture makes Redis suitable for:
The codebase supports four deployment modes:
redisServer instancesentinel.c state machineSources: src/server.h1-100 src/server.c79-83 redis.conf1-100
Redis is built on three core principles:
Single-threaded command execution: All commands execute sequentially in call() within the main thread, eliminating lock contention and ensuring atomic operations without transactions for most use cases.
Event-driven I/O: The aeEventLoop in src/ae.h multiplexes all socket operations, allowing a single thread to handle thousands of concurrent connections.
In-memory first: All active data resides in server.db[] hash tables. Persistence (rdb.c, aof.c) and replication (replication.c) are secondary concerns that don't block command processing.
Sources: src/server.c79-83 src/ae.c src/networking.c1-300
Diagram: Server Initialization and Event Loop
The main() function at src/server.c6500-6800 initializes the global struct redisServer server and enters the event loop. Key initialization steps:
initServer() at src/server.c2800-3200:
server.db[] array (default 16 databases)server.clients listserver.commands dict with command tableaeCreateEventLoop() to set up epoll/kqueue/selectlistenToPort()aeMain() at src/ae.c:
while (!server.stop)beforeSleep() to flush client output buffersserverCron fires every 100ms)serverCron() at src/server.c1300-1800:
Sources: src/server.c2800-3200 src/server.c6500-6800 src/ae.c
Diagram: Command Execution Path with Code Entities
Commands flow through these functions:
readQueryFromClient() at src/networking.c2000-2200: Reads bytes from c->conn into c->querybuf (an sds string).
processInputBuffer() at src/networking.c2100-2300: Parses RESP protocol, populates c->argc and c->argv[] array.
processCommand() at src/server.c3800-4200:
lookupCommand() to search server.commands dictACLCheckAllPerm()getNodeByQuery() to check slot ownershipCMD_DENYOOM flag setcall() at src/server.c3500-3700:
cmd->proc function pointer (e.g., setCommand, getCommand)propagateNow() to append to AOF and replicate to slavesCommand implementation (e.g., setCommand at src/t_string.c):
lookupKeyWrite() or lookupKeyRead() to access db->keys kvstoreaddReply() to build responseaddReply*() functions at src/networking.c400-800: Write RESP-encoded data to c->buf (static buffer) or c->reply (linked list of clientReplyBlock).
Sources: src/networking.c2000-2300 src/server.c3500-4200 src/db.c274-333
The entire server state resides in a single global variable:
Diagram: struct redisServer Key Fields
The redisServer struct at src/server.h1800-2500 contains:
| Field | Type | Purpose |
|---|---|---|
db[] | redisDb array | 16 numbered databases (default), each with independent keyspace |
commands | dict* | Command table mapping name (sds) to redisCommand* |
clients | list* | All connected client* structures |
el | aeEventLoop* | Event loop for socket multiplexing |
aof_state | int | AOF enabled status (AOF_OFF/ON/WAIT_REWRITE) |
masterhost | sds | Master hostname if this is a replica (NULL otherwise) |
cluster_enabled | int | Whether cluster mode is active |
maxmemory | long long | Memory limit for eviction |
maxmemory_policy | int | Eviction algorithm (LRU/LFU/LRM/RANDOM/TTL) |
Each redisDb struct at src/server.h700-750 contains:
| Field | Type | Purpose |
|---|---|---|
keys | kvstore* | Main keyspace (slot-sharded hash tables) |
expires | kvstore* | Expiration times for keys with TTL |
id | int | Database number (0-15) |
Sources: src/server.h1800-2500 src/server.h700-750 src/server.c84
Diagram: From redisDb to Data Type Encodings
The kvobj structure at src/server.h70-93 unifies keys and values:
For keys stored in db->keys:
iskvobj=1: The key (sds string) is embedded after the structmetabits: Bitmask indicating presence of expiry timestamp and other metadataptr: Points to the value's data structure (quicklist, dict, skiplist, etc)The kvobjCreate() function at src/object.c62-105 allocates a kvobj with embedded key and metadata space.
Sources: src/server.h70-93 src/object.c62-105 src/db.c274-333
The dict structure at src/dict.h implements generic hash tables:
Key operations:
dictFind() at src/dict.c400-450: Hash key, probe chain, return entrydictAdd() at src/dict.c500-550: Insert new key-value pairdictRehash() at src/dict.c600-700: Incremental rehashing (moves N buckets)The kvstore wrapper at src/kvstore.c manages multiple dicts for slot-based sharding in cluster mode. In standalone mode, it contains a single dict. In cluster mode, it contains up to 16,384 dicts (one per hash slot).
Sources: src/dict.h src/dict.c400-700 src/kvstore.c
| Type | Constant | Small Encoding | Large Encoding | Implementation File |
|---|---|---|---|---|
| String | OBJ_STRING | OBJ_ENCODING_EMBSTR (ā¤44 bytes) | OBJ_ENCODING_RAW (sds) | src/t_string.c |
| List | OBJ_LIST | ā | OBJ_ENCODING_QUICKLIST | src/t_list.c |
| Set | OBJ_SET | OBJ_ENCODING_INTSET | OBJ_ENCODING_HT (dict) | src/t_set.c |
| Sorted Set | OBJ_ZSET | OBJ_ENCODING_LISTPACK | OBJ_ENCODING_SKIPLIST | src/t_zset.c |
| Hash | OBJ_HASH | OBJ_ENCODING_LISTPACK | OBJ_ENCODING_HT (dict) | src/t_hash.c |
| Stream | OBJ_STREAM | ā | OBJ_ENCODING_STREAM (rax) | src/t_stream.c |
Encoding transitions are triggered by configuration thresholds:
hash-max-listpack-entries / hash-max-listpack-valueset-max-intset-entrieszset-max-listpack-entries / zset-max-listpack-valueEach data type's commands are implemented in t_<type>.c files and registered in the command table at src/commands.c
Sources: src/server.h600-800 src/t_string.c src/t_list.c src/t_set.c src/t_zset.c src/t_hash.c src/t_stream.c src/commands.c
Redis offers two persistence strategies that can operate independently or together:
Diagram: RDB Save Process
The RDB format at src/rdb.c1-300 is a binary snapshot of the entire dataset:
SAVE (blocking), BGSAVE (background), or save config intervalsfork() creates child, iterates all databases, serializes each key-value pairrdbLoad() at src/rdb.c2800-3200 reads dump.rdb on startupAdvantages: Compact, fast loading
Disadvantages: Data loss window between snapshots
Sources: src/rdb.c1-300 src/rdb.c2800-3200 src/rdb.h
Diagram: Multi-Part AOF System
The AOF system at src/aof.c logs write commands:
appendfsync always|everysec|no in redis.confaofManifest struct tracks all files at src/aof.c143-172rewriteAppendOnlyFile() at src/aof.c2000-2500 forks and generates minimal command sequenceLoading process:
appendonly.aof.manifest to get file listSources: src/aof.c1-300 src/aof.c1100-1300 src/aof.c2000-2500
Diagram: PSYNC Protocol State Machine
Replication at src/replication.c implements master-replica synchronization:
Master side:
replicationFeedSlaves() at src/replication.c400-600: Sends commands to all replicasserver.repl_backlog: Circular buffer (default 1MB) for partial resyncserver.slaves: List of client* with CLIENT_SLAVE flagReplica side:
replicationCron() at src/replication.c3000-3300PSYNC <runid> <offset>: Request partial sync if possiblereadSyncBulkPayload(): Receive RDB during full syncPSYNC2 features:
server.replid2)Sources: src/replication.c1-300 src/replication.c3000-3300 src/server.h1800-2000
| Mode | File | Purpose | Key Structures |
|---|---|---|---|
| Standalone | server.c | Single instance | redisServer |
| Master-Replica | replication.c | Async replication for read scaling | server.master, server.slaves |
| Sentinel | sentinel.c | Monitor masters and auto-failover | sentinelState |
| Cluster | cluster.c | Sharded keyspace (16384 slots) | clusterState, clusterNode |
For cluster and sentinel details, see sections 6.1 and 6.2.
Sources: src/server.c src/replication.c src/sentinel.c src/cluster.c
Lua and Functions system at src/script_lua.c src/functions.c:
redis.call() / redis.pcall()server.functions)Script execution at src/eval.c:
evalGenericCommand() compiles Lua codescriptRunCtx with time limit (lua-time-limit)luaRedisCallCommand() go through normal call() pathSources: src/script_lua.c src/eval.c src/functions.c
Diagram: Module System Architecture
Modules are .so files loaded at runtime via src/module.c1000-1200:
RedisModule_OnLoad(RedisModuleCtx *ctx, RedisModuleString **argv, int argc)RedisModule_CreateCommand(ctx, "mycommand", myCommandFunc, "write", ...)RedisModule_CreateDataType() with RDB save/load callbacksRedisModule_OpenKey(), RedisModule_Call() to execute commandsThe module API (120+ functions) at src/redismodule.h includes:
RedisModule_Alloc(), RedisModule_Free()RedisModule_OpenKey(), RedisModule_CloseKey()RedisModule_Replicate(), RedisModule_ReplicateVerbatim()RedisModule_BlockClient(), RedisModule_UnblockClient()RedisModule_SubscribeToKeyspaceEvents()Sources: src/module.c1-500 src/module.c1000-1200 src/redismodule.h1-200
Redis configuration at src/config.c is managed through:
Configuration Loading:
loadServerConfigFromString() at src/config.c450-800: Parse redis.confstandardConfig table at src/config.c2800-4000: Defines all settingsconfigs dict: Maps config name (sds) to standardConfig*Runtime Changes:
CONFIG GET <pattern>: Returns matching configsCONFIG SET <name> <value>: Modifies running configCONFIG REWRITE: Writes current values back to redis.confKey Config Categories:
| Category | Example Directives | Implementation |
|---|---|---|
| Memory | maxmemory, maxmemory-policy | src/config.c3000-3100 |
| Persistence | save, appendonly, aof-fsync | src/config.c3200-3400 |
| Networking | bind, port, tcp-backlog | src/config.c2900-3000 |
| Security | requirepass, aclfile | src/config.c3500-3600 |
| Replication | replicaof, repl-diskless-sync | src/config.c3700-3900 |
| Cluster | cluster-enabled, cluster-config-file | src/config.c4000-4100 |
Each standardConfig defines:
name: Config directive stringset(): Function to validate and apply valueget(): Function to read current valuerewrite(): Function to format for redis.confSources: src/config.c450-1000 src/config.c2800-4200 redis.conf1-500
The distribution includes command-line utilities:
| Tool | File | Purpose |
|---|---|---|
| redis-server | server.c | Main daemon (also Sentinel with --sentinel) |
| redis-cli | redis-cli.c | Interactive REPL client |
| redis-benchmark | redis-benchmark.c | Performance testing and latency measurement |
| redis-check-rdb | redis-check-rdb.c | Validate/repair RDB files |
| redis-check-aof | redis-check-aof.c | Validate/repair AOF files |
redis-cli features at src/redis-cli.c:
redis-cli -c follows redirectionsecho "SET key val" | redis-cli --piperedis-cli --resp3--bigkeys, --memkeys, --latencyredis-benchmark features at src/redis-benchmark.c:
redis-benchmark -t SET,GET -n 100000redis-benchmark -P 16redis-benchmark --clusterSources: src/redis-cli.c1-500 src/redis-benchmark.c1-500
Based on code importance metrics (edit frequency Ć impact), the codebase subsystems are:
| Subsystem | Primary Files | Importance | Description |
|---|---|---|---|
| Core Server | server.c, server.h | 927.74 | Global state, event loop, cron tasks |
| Networking | networking.c | 682.68 | Client I/O, RESP parsing, reply buffers |
| Module API | module.c | 718.53 | Dynamic module loading and API |
| Configuration | config.c | 439.59 | Runtime config management |
| Database | db.c | 436.90 | Key lookup, expiration, notifications |
| Replication | replication.c | 421.22 | PSYNC protocol, backlog, replica management |
| RDB | rdb.c | 391.22 | Binary snapshots, save/load |
| AOF | aof.c | 286.66 | Append-only file, manifest, rewrite |
| Data Types | t_string.c, t_list.c, t_set.c, t_zset.c, t_hash.c, t_stream.c | Various | Type-specific commands |
| Cluster | cluster.c, cluster_asm.c | Various | Sharding, slot migration |
| Sentinel | sentinel.c | Medium | Failover and monitoring |
src/
āāā server.c/h # Main server and global state
āāā networking.c # Client connection handling
āāā ae.c/h # Event loop (epoll/kqueue/select)
āāā db.c # Database operations
āāā object.c # Object allocation (robj/kvobj)
āāā dict.c/h # Hash table implementation
āāā kvstore.c/h # Slot-based dict wrapper
āāā sds.c/h # Dynamic string library
āāā t_*.c # Data type implementations
āāā commands.c # Command table definition
āāā config.c # Configuration system
āāā rdb.c # RDB persistence
āāā aof.c # AOF persistence
āāā replication.c # Master-replica sync
āāā cluster.c # Cluster mode
āāā sentinel.c # Sentinel mode
āāā module.c # Module API
āāā script_lua.c # Lua scripting
āāā functions.c # Function library
āāā acl.c # Access control lists
āāā evict.c # Eviction policies
āāā expire.c # Key expiration
āāā lazyfree.c # Background deletion
āāā bio.c # Background I/O threads
Sources: src/server.c1-100 src/networking.c1-100 src/module.c1-100
The zmalloc layer at src/zmalloc.c wraps the underlying allocator:
Supported allocators (configure with USE_JEMALLOC, USE_TCMALLOC):
All allocations update server.stat_alloced_bytes for INFO memory reporting.
When used_memory exceeds maxmemory, eviction at src/evict.c removes keys based on policy:
| Policy | Constant | Behavior |
|---|---|---|
| volatile-lru | MAXMEMORY_VOLATILE_LRU | LRU among keys with TTL |
| volatile-lfu | MAXMEMORY_VOLATILE_LFU | LFU among keys with TTL |
| volatile-ttl | MAXMEMORY_VOLATILE_TTL | Soonest expiring keys |
| allkeys-lru | MAXMEMORY_ALLKEYS_LRU | LRU among all keys |
| allkeys-lfu | MAXMEMORY_ALLKEYS_LFU | LFU among all keys |
| allkeys-lrm | MAXMEMORY_ALLKEYS_LRM | LRM (Least Recently Modified) among all keys |
| noeviction | MAXMEMORY_NO_EVICTION | Return errors on OOM |
Eviction function evictData() at src/evict.c600-800 uses a sampling pool to avoid full dataset scan.
Bio (Background I/O) threads at src/bio.c1-200:
BIO_CLOSE_FILE: Close file descriptors asynchronouslyBIO_AOF_FSYNC: Fsync AOF in backgroundBIO_LAZY_FREE: Delete large objects (lists, sets, hashes) without blockingLazy free at src/lazyfree.c:
dbAsyncDelete(): Queue key deletion to bio threadfreeObjAsync(): Schedule large object freeingSources: src/zmalloc.c1-200 src/evict.c600-900 src/bio.c1-200 src/lazyfree.c1-200
Redis is single-threaded for command execution to ensure:
Optional threading:
| Thread Type | Config | Purpose |
|---|---|---|
| I/O threads | io-threads <N> | Parallelize socket read/write (networking.c) |
| BIO threads | Always on (3 threads) | Background file close, AOF fsync, lazy free |
| Module threads | Created by modules | Blocking operations, background work |
I/O threading at src/networking.c3500-3800:
io-threads > 1c->querybufc->buf to socketsSources: src/networking.c3500-3800 src/bio.c1-100 src/server.h2300-2400
For deeper dives into specific subsystems:
Redis is a high-performance in-memory data store with:
The codebase centers around the struct redisServer server global state, an event-driven networking layer, and a command processing pipeline that routes requests to data type implementations.
Sources: src/server.h1800-2500 src/server.c1-300 redis.conf1-100
Refresh this wiki