ZK.← Selected work
Backend / NetworkingMaintained

Project / 02

Mini Redis Server

A deliberately small Redis-compatible C++ server that accepts RESP commands over POSIX TCP sockets, stores strings in memory, coordinates clients with threads and a mutex, and persists data to disk.

Architecture / Request path

How the pieces connect.

  1. 01TCP client
  2. 02RESP parser
  3. 03Command handler
  4. 04Locked database
  5. 05Disk file

01 / Problem

Why I built it

Redis looks simple from a client: send a command and receive a response. I built a minimal compatible server to understand the socket lifecycle, protocol boundary, shared state, and persistence behind that interaction.

02 / Design

System shape

The implementation is divided into four responsibilities. Server accepts clients, Resp translates network messages, CommandHandler validates operations, and Database owns the synchronized unordered_map plus persistence. main only wires those pieces together.

03 / Implementation

What the code actually does

  • 01

    POSIX socket, bind, listen, accept, receive, and send flow

  • 02

    RESP parsing and Redis-compatible response encoding

  • 03

    PING, SET, GET, DEL, KEYS *, and SAVE commands

  • 04

    One worker thread per client with a mutex protecting shared data

  • 05

    Startup loading plus automatic persistence after SET and DEL

04 / Decisions

Engineering choices

01

Keep the scope readable

The server stores strings only and intentionally avoids reproducing Redis as a whole. That keeps the networking and protocol path understandable end to end.

02

Give each layer one job

Protocol parsing, command selection, storage, and socket management live in separate classes, so each can change without rewriting the others.

03

Persist visible state

Saving after mutations makes restart behavior easy to demonstrate and gave the maze visualizer a dependable external store.

Concrete outcomes

01
6 Redis commands
02
Thread per client
03
Automatic persistence

Observed while building

  • A protocol is a contract between independent programs, not merely a parsing format.
  • Shared in-memory state becomes a concurrency problem as soon as multiple clients can connect.
  • The current full-command-per-read assumption is intentionally simple and marks the boundary for a buffered parser.

Next iteration

Add buffered RESP parsing, expiry support, richer data types, and an event-driven connection model while preserving the current readable architecture.

C++RESPPOSIX SocketsMultithreading