GoRedis
2026Redis-compatible database, written from scratch
GoRedis is an in-memory database written from scratch in Go. It speaks the RESP wire protocol, so the official redis-cli and existing client libraries connect without knowing the difference. It has strings with TTL, lists with blocking pops, streams with consumer groups, sorted sets on a skip list and geospatial indexes, plus MULTI/EXEC transactions with WATCH, master-replica replication, RDB snapshots, an append-only log, Pub/Sub and password auth.
- Go
- TCP
- RESP
Why build Redis
I use Redis all the time without thinking about how it works. Writing one from scratch in Go was a way to see where its design choices come from (protocol parsing, expiration, blocking operations, replication, persistence) instead of only reading about them.
The bar I set: implement enough of the protocol that the real redis-cliand existing client libraries can connect without noticing they're talking to a different server.
Build phases
- 01
Foundation
TCP server that speaks the RESP wire protocol: PING/PONG, ECHO, then SET/GET. Connection lifecycle and a per-connection request loop.
- 02
Concurrency
Goroutine-per-connection model. Many clients in flight at once; shared in-memory store guarded by fine-grained locking.
- 03
Data structures
Strings with TTL and lazy expiration, lists with blocking ops (BLPOP), sorted sets via skip-lists, streams with consumer groups, geospatial.
- 04
Transactions
MULTI / EXEC queueing with WATCH-based optimistic concurrency that aborts on conflict instead of locking.
- 05
Replication
Master-to-replica replication through command propagation, replication offsets, partial resync.
- 06
Persistence
RDB binary snapshots for fast restarts and an AOF write-ahead log for durability. Tunable fsync policy.
- 07
Pub/Sub & auth
SUBSCRIBE / PUBLISH fan-out and password-based auth.
Architecture
Single-binary TCP server. One goroutine per client connection reads RESP frames into a command dispatcher; commands operate on an in-memory keyspace and append to an AOF buffer that's fsynced per the configured policy. A background expirer sweeps TTLs. A separate replication goroutine streams write commands to attached replicas over the same RESP protocol.
Highlights
- A hand-written RESP parser, so redis-cli and client libraries connect natively. In-memory GET/SET stays under a millisecond.
- Strings with TTL, lists with blocking operations (BLPOP), streams with consumer groups, sorted sets on a skip list, and geospatial indexing.
- MULTI/EXEC transactions with WATCH-based optimistic concurrency, plus master-replica replication, RDB snapshots, AOF logging, Pub/Sub and auth.
Commands implemented
A hand-written RESP parser backs the dispatcher, so every command below is wire-compatible with the official redis-cli and standard client libraries: the same commands, replies and error shapes.
Connection & server
- PING
- ECHO
- INFO
- TYPE
Strings
- SET
- GET
- INCR
Lists
- RPUSH
- LPUSH
- LRANGE
- LLEN
- LINDEX
- LPOP
- RPOP
- BLPOP
Streams
- XADD
- XRANGE
- XREAD
Transactions
- MULTI
- EXEC
- DISCARD
- WATCH
- UNWATCH
Sorted sets
- ZADD
- ZRANK
- ZCARD
- ZRANGE
- ZSCORE
- ZREM
Geospatial
- GEOADD
- GEOPOS
- GEODIST
- GEORADIUS
Pub/Sub
- SUBSCRIBE
- UNSUBSCRIBE
- PUBLISH
Replication
- REPLCONF
- PSYNC
- WAIT
Auth
- ACL