A small, concurrent, Redis-compatible in-memory database server written from scratch in Go.
memdb speaks the RESP (REdis Serialization Protocol) over TCP, so it works directly with the official redis-cli—no custom client or adapter required. It is a focused systems project that explores the pieces behind a real database server: wire protocols, connection handling, command dispatch, concurrency, and predictable in-memory storage.
Rather than wrapping an existing database, memdb implements the server side itself:
- Parses and writes RESP frames, including simple strings, errors, integers, bulk strings, and arrays.
- Listens on TCP port
6379and handles each client connection in its own goroutine. - Uses a
sync.RWMutex-protected hash map for safe concurrent reads and writes. - Maps commands to small, isolated handlers and returns protocol-correct Redis-style responses.
- Emits structured server logs with Zap.
Prerequisite: Go 1.26.4 or newer (see go.mod).
git clone https://github.com/zyncc/memdb.git
cd memdb
go run .With the server running, open another terminal and use the official Redis CLI:
redis-cli
127.0.0.1:6379> PING
PONG
127.0.0.1:6379> SET candidate "ships systems projects"
OK
127.0.0.1:6379> GET candidate
"ships systems projects"
127.0.0.1:6379> DEL candidate
(integer) 1| Command | Description |
|---|---|
PING |
Health check; returns PONG. |
ECHO <message> |
Returns the supplied message as a bulk string. |
SET <key> <value> |
Stores a string value. |
GET <key> |
Retrieves a value or returns a RESP null bulk string. |
DEL <key> [key ...] |
Deletes one or more keys. |
Command names are case-insensitive. Unknown commands and invalid request shapes receive RESP error replies.
redis-cli / RESP client
│ TCP + RESP
▼
connection goroutine
│
▼
RESP reader → command dispatcher → Store (map + RWMutex)
│ │
└──────── RESP writer ◄────────┘
The design deliberately keeps the protocol layer (resp.go), network/dispatch layer (main.go), and storage/command layer (store.go) separate, making it easy to extend with additional commands or data structures.
memdb is intentionally an educational, in-memory implementation—not a replacement for Redis. Data is not persisted, and only a focused subset of Redis commands is currently supported. Natural extensions include expirations, richer data types, persistence, command tests, and graceful shutdown.
main.go TCP listener, client lifecycle, and command routing
resp.go RESP encoder and decoder
store.go Concurrent key-value store and command handlers
Built to learn the internals behind a production-style networked datastore, one protocol frame at a time.