Skip to content

Redis Master Memory Map: The Connected Neural Architecture

This document is your single-glance visual memory map and revision blueprint for Redis. Every component, C struct, memory arena, background thread, persistence file, and cluster socket is mapped as a connected graph so you can trace how every dot connects to every other dot in the Redis engine.


1. The Master Visual Memory Maps (Modular Deep-Zoom System)

All diagrams follow a uniform top-to-bottom (graph TD) layout with consistent color-coded nodes.


1.1 The Executive Macro Ecosystem (The 30,000-Foot View)

graph TD
    classDef client fill:#e1f5fe,stroke:#0288d1,color:#01579b;
    classDef engine fill:#ede7f6,stroke:#512da8,color:#311b92;
    classDef mem fill:#e8f5e9,stroke:#388e3c,color:#1b5e20;
    classDef disk fill:#fbe9e7,stroke:#d84315,color:#bf360c;
    classDef net fill:#e0f2f1,stroke:#00796b,color:#004d40;

    subgraph CLIENT_TIER ["1. Client & Network Ingress Tier"]
        C1[Client Applications]:::client -->|TCP Sockets| IOT["Threaded I/O Workers: Socket Read/Write"]:::net
        IOT -->|Parsed Commands| EL["ae Event Loop: Single-Threaded Core"]:::engine
    end

    subgraph MEMORY_TIER ["2. In-Memory Keyspace & Allocator Tier"]
        EL <-->|"Dict / SDS / Skiplist"| DB[("redisDb Keyspace")]:::mem
        DB <-->|"Arenas & Bins"| JEM[Jemalloc Memory Allocator]:::mem
        EL -->|Eviction Pool| EVIC["LRU / LFU Maxmemory Engine"]:::mem
    end

    subgraph PERSISTENCE_TIER ["3. Durability & Disk Persistence Tier"]
        EL -->|fork Copy-on-Write| RDB["RDB Snapshot: dump.rdb"]:::disk
        EL -->|Sequential Buffer| AOF["AOF Log: appendonly.aof"]:::disk
    end

    subgraph CLUSTER_TIER ["4. High Availability & Cluster Tier"]
        EL -->|Replication Stream| REPL[Replicas via PSYNC2]:::net
        EL <-->|Cluster Bus Port 16379| GOSSIP["Redis Cluster: 16384 Hash Slots"]:::net
    end

1.2 Regional Map 1: The Event Loop & Command Processing Engine

graph TD
    classDef proc fill:#ede7f6,stroke:#512da8,color:#311b92;
    classDef mem fill:#e8f5e9,stroke:#388e3c,color:#1b5e20;
    classDef priv fill:#fff3e0,stroke:#f57c00,color:#e65100;

    EPOLL["Kernel I/O Multiplexer: Epoll / Kqueue"]:::proc -->|Fires Socket Event| AE[aeProcessEvents Engine]:::proc
    AE -->|File Events| READ[readQueryFromClient]:::proc
    AE -->|Time Events| CRON["serverCron: 100ms Periodic Tasks"]:::proc

    READ -->|Appends raw bytes| QBUF["client->querybuf: SDS Buffer"]:::priv
    QBUF -->|Splits into Arguments| ARGV["client->argv: robj Array"]:::priv
    ARGV -->|Lookup Command Name| CMD["server.commands: Command Table Hash"]:::mem

    CMD -->|Atomic Execution| EXEC["proc Function Pointer: e.g. setCommand"]:::proc
    EXEC -->|Modifies Keyspace| DB[("server.db: dict")]:::mem
    EXEC -->|Appends Response| OUTBUF["client->buf: 16KB Static Buffer"]:::priv

    AE -->|beforeSleep Loop| FLUSH["writeToClient: Flushes outbuf to Socket"]:::proc
    OUTBUF --> FLUSH

1.3 Regional Map 2: Cellular Anatomy of Redis Data Structures

graph TD
    classDef obj fill:#ede7f6,stroke:#512da8,color:#311b92;
    classDef struct fill:#e8f5e9,stroke:#388e3c,color:#1b5e20;
    classDef mem fill:#fff3e0,stroke:#f57c00,color:#e65100;

    KSPC[redisDb dict]:::obj -->|Points to Value| ROBJ["redisObject: 16 Bytes"]:::obj

    ROBJ --- T["type: 4 bits String/List/Set/ZSet/Hash"]:::struct
    ROBJ --- E["encoding: 4 bits raw/embstr/listpack/skiplist"]:::struct
    ROBJ --- L["lru: 24 bits LRU timestamp or LFU counter"]:::struct
    ROBJ --- R["refcount: 32 bits shared object counter"]:::struct
    ROBJ --- P["ptr: 64-bit Pointer to Actual Payload"]:::struct

    P -->|If String| SDS["SDS: Simple Dynamic String"]:::mem
    SDS --- SDSH["sdshdr8: len, alloc, flags, buf"]:::mem

    P -->|"If Small Hash / List"| LP["Listpack: Contiguous Compact Array"]:::mem
    LP --- LPE[Total Bytes, Num Elements, Back-length entries]:::mem

    P -->|If Large List| QL["Quicklist: Doubly-Linked List of Listpacks"]:::mem

    P -->|If Sorted Set ZSET| ZS[zset Dual Structure]:::mem
    ZS -->|O 1 Score Lookup| ZD["dict: member to score"]:::struct
    ZS -->|O logN Range Search| ZSL["zskiplist: Forward pointers and Spans"]:::struct

1.4 Regional Map 3: Persistence, Replication & Clustering Pipeline

graph TD
    classDef proc fill:#ede7f6,stroke:#512da8,color:#311b92;
    classDef mem fill:#e8f5e9,stroke:#388e3c,color:#1b5e20;
    classDef disk fill:#fbe9e7,stroke:#d84315,color:#bf360c;
    classDef net fill:#e0f2f1,stroke:#00796b,color:#004d40;

    MAIN[Main Redis Process]:::proc -->|"BGSAVE: Linux fork"| CHILD["Child Process: RDB Dumper"]:::proc
    MAIN -.->|Modifies memory during dump| COW[Linux OS Copy-on-Write Page Split]:::mem
    CHILD -->|Serializes RAM to disk| RDBF[("dump.rdb Binary File")]:::disk

    MAIN -->|Every mutation| AOFBUF["server.aof_buf: SDS Memory Buffer"]:::mem
    AOFBUF -->|write system call| OSBUF[OS Page Cache Kernel Buffer]:::mem
    OSBUF -->|"fsync policy: everysec"| AOFF[("appendonly.aof Disk File")]:::disk

    MAIN -->|Feeds mutation stream| REPLBUF["server.repl_backlog: Circular Ring Buffer"]:::mem
    REPLBUF -->|PSYNC2 replication stream| SLAVE[Replica Node]:::net
    MAIN <-->|Cluster Bus Port 16379| GOSSIP["Gossip Mesh: 16384 Hash Slots"]:::net

2. The 3 Primary Pathways in Motion (Visual Interactive Traces)


Pathway A: Trace of a Write Command (SET user:100 "active" EX 3600)

sequenceDiagram
    autonumber
    actor Client as "Client App"
    participant Epoll as "Epoll Event Loop"
    participant BE as "Redis Main Thread"
    participant Dict as "redisDb (dict)"
    participant Expire as "db->expires (dict)"
    participant AOF as "aof_buf"
    participant Repl as "repl_backlog"

    Client->>Epoll: Sends TCP packet: *4\r\n$3\r\nSET...
    Epoll->>BE: Fires readable event on client socket
    BE->>BE: readQueryFromClient(): Parses arguments into client.argv
    BE->>BE: Lookup "set" in server.commands table
    BE->>Dict: dictAddOrUpdate(db.dict, "user:100", "active")
    BE->>Expire: dictAdd(db.expires, "user:100", now() + 3600s)
    BE->>AOF: feedAppendOnlyFile(): Appends raw RESP command
    BE->>Repl: replicationFeedSlaves(): Pushes into circular ring buffer
    BE->>Client: addReply(): Writes "+OK\r\n" to client.buf (16KB static)
    Note over BE,Client: beforeSleep() flushes client.buf to socket!

Pathway B: Trace of Memory Eviction & Expiration

sequenceDiagram
    autonumber
    participant Client as "Incoming Write Query"
    participant Server as "server.c Engine"
    participant Expire as "Active Expire Cycle"
    participant Evic as "Eviction Pool (Maxmemory)"
    participant JEM as "Jemalloc Allocator"

    Note over Expire: serverCron runs every 100ms:
    Expire->>Expire: activeExpireCycle(): Samples 20 random keys from db.expires
    Expire->>JEM: Deletes expired keys immediately and reclaims RAM

    Client->>Server: Heavy write query arrives (RAM usage greater than  maxmemory)
    Server->>Evic: performEvictions(): Sizing eviction pool
    Evic->>Evic: Samples N random keys (default 5) into 16-element Eviction Pool
    Evic->>Evic: Sorts pool by idle time (LRU) or logarithmic counter (LFU)
    Evic->>JEM: Evicts best candidate key using dbAsyncDelete (UNLINK)
    JEM-->>Server: Physical memory arena reclaimed
    Server->>Client: Executes incoming write query safely

Pathway C: Trace of Fork Copy-on-Write (COW) Persistence

sequenceDiagram
    autonumber
    participant Main as "Redis Main Process (PID 1000)"
    participant Linux as "Linux OS Kernel"
    participant Child as "Child Process (PID 1001)"
    participant Disk as "Physical Disk (dump.rdb)"

    Main->>Linux: fork() system call invoked by BGSAVE
    Linux->>Linux: Duplicates page table pointers (Zero memory copy!)
    Linux-->>Child: Spawns Child Process with identical read-only memory view
    Child->>Disk: Sequentially iterates keyspace and writes dump.rdb

    Note over Main,Linux: Incoming high-throughput writes arrive at Main Process:
    Main->>Linux: Modifies memory page 42
    Linux->>Linux: MMU triggers Page Fault to Allocates NEW 4KB physical page
    Linux->>Linux: Copies original page 42 bytes to new page for Main Process
    Note over Main,Linux: Child process continues reading original page 42 without locking!
    Child->>Disk: Finalizes dump.rdb and issues fsync()
    Child-->>Main: Exits with code 0 (SIGCHLD)

3. Quick Revision Flashcard Matrix ("Connect the Cause to the Effect")

If this "Dot" changes / breaks... Which connected "Dot" immediately suffers? Why? (The Mechanical Link)
A developer runs KEYS * or HGETALL on a 1M element hash All connected clients & Sentinel health-checks Single-threaded execution means no other socket or timer event can be processed until the \(O(N)\) command completes. Sentinel detects timeout and triggers false failovers.
transparent_hugepage is enabled in Linux kernel Memory amplification during BGSAVE When the main thread writes to memory during fork COW, the OS must copy an entire 2MB hugepage instead of a fine-grained 4KB page, doubling or tripling memory consumption and triggering OOM kills.
A replica falls behind by more than repl-backlog-size Primary server disk I/O & Network Partial resynchronization (PSYNC2) fails. Primary is forced to fork an entire full RDB snapshot (BGSAVE), ship the multi-gigabyte file over the wire, and force the replica to wipe its memory and reload.
client-output-buffer-limit slave is set too low Replication stability High write throughput fills the replica's output buffer faster than the network can drain it. Redis disconnects the replica, throwing the cluster into an infinite full-resync disconnect loop.
A string key is appended repeatedly past 44 bytes Memory allocation efficiency Redis dynamically flips object encoding from OBJ_ENCODING_EMBSTR (single allocation of robj + SDS) to OBJ_ENCODING_RAW (two separate malloc allocations), increasing memory fragmentation and pointer chasing.
appendfsync is set to always Write throughput (\(100\text{k req/s} \rightarrow 1\text{k req/s}\)) The main execution thread blocks on every single write command until the physical disk drive controller flushes the byte to non-volatile storage via fsync.
A Hash table expands without progressive rehashing Query latency spikes Reallocating a 10-million key hash table in a single blocking step would freeze the server for seconds. Redis solves this by progressively moving 1 bucket per user query (dictRehashStep).
maxmemory-policy is left as default noeviction Application writes Once RAM reaches maxmemory, all write operations (SET, HSET, LPUSH) fail immediately with OOM command not allowed when used memory > 'maxmemory'. Reads remain functional.