A feature-rich Redis server implementation in Go, built as part of the CodeCrafters Redis challenge. This project implements the Redis Serialization Protocol (RESP) and supports a wide range of Redis commands and features.
# Pull and run from Docker Hub
docker pull seanxunx/redigo:latest
docker run -p 6379:6379 seanxunx/redigo:latest
# Connect with redis-cli
redis-cli -h localhost -p 6379- Strings - Basic key-value operations with expiration support
- Lists - LPUSH, RPUSH, LPOP, LRANGE, LLEN, and blocking operations (BLPOP)
- Sorted Sets - ZADD, ZRANK, ZRANGE, ZCARD, ZSCORE, ZREM
- Streams - XADD, XRANGE, XREAD for event streaming
- Geospatial - GEOADD, GEOPOS, GEODIST, GEOSEARCH for location-based queries
- Master-Slave Replication - Full replication support with PSYNC
- RDB Persistence - Load and save data from/to RDB files
- Transactions - MULTI, EXEC, DISCARD for atomic operations
- Pub/Sub - SUBSCRIBE, PUBLISH, UNSUBSCRIBE for messaging
- Blocking Operations - BLPOP with timeout support
- RESP Protocol - Full Redis Serialization Protocol implementation
PING- Test server connectivityECHO- Echo the given stringCOMMAND- Get command infoINFO- Server informationCONFIG- Configuration managementKEYS- Find keys matching patternTYPE- Determine key type
SET- Set key to value with optional expiration (PX, EX)GET- Get value of keyINCR- Increment key value
RPUSH- Push to right of listLPUSH- Push to left of listLPOP- Pop from left of listBLPOP- Blocking pop from left of listLRANGE- Get range of elementsLLEN- Get list length
ZADD- Add member with scoreZRANK- Get member rankZRANGE- Get range by indexZCARD- Get set cardinalityZSCORE- Get member scoreZREM- Remove members
XADD- Add entry to streamXRANGE- Query range of entriesXREAD- Read from streams (with blocking support)
GEOADD- Add location coordinatesGEOPOS- Get position of membersGEODIST- Get distance between membersGEOSEARCH- Search by radius or box
SUBSCRIBE- Subscribe to channelsPUBLISH- Publish message to channelUNSUBSCRIBE- Unsubscribe from channels
MULTI- Start transactionEXEC- Execute transactionDISCARD- Discard transaction
REPLCONF- Replication configurationPSYNC- Synchronize with masterWAIT- Wait for replication acknowledgment
.
βββ app/
β βββ main.go # Entry point
β βββ server/ # TCP server and connection handling
β β βββ server.go # Server implementation
β β βββ conn_handler.go # Command execution
β β βββ parser.go # RDB file parser
β βββ resp/ # RESP protocol encoder/decoder
β β βββ encoder.go
β β βββ decoder.go
β β βββ utils.go
β βββ kv/ # Key-value store implementations
β β βββ kv.go # Main store
β β βββ string.go # String operations
β β βββ list.go # List operations
β β βββ zset.go # Sorted set operations
β β βββ stream.go # Stream operations
β β βββ geo.go # Geospatial operations
β β βββ transaction.go # Transaction support
β βββ geospatial/ # Geospatial utilities
β βββ geohash.go # Geohash encoding
β βββ distance.go # Distance calculations
βββ Dockerfile
βββ docker-compose.yml
βββ go.mod
βββ go.sum
- Go 1.25.0 or higher
- Docker (optional)
# Run as master on default port 6379
go run ./app/main.go
# Run on custom port
go run ./app/main.go -port 6380
# Run as replica
go run ./app/main.go -port 6380 -replicaof "localhost 6379"
# Run with RDB persistence
go run ./app/main.go -dir /tmp/redis -dbfilename dump.rdb# Pull the latest image
docker pull seanxunx/redigo:latest
# Run as master
docker run -p 6379:6379 seanxunx/redigo:latest
# Run with custom port
docker run -p 6380:6379 seanxunx/redigo:latest
# Run with volume for RDB persistence
docker run -p 6379:6379 -v $(pwd)/data:/data \
seanxunx/redigo:latest -dir /data -dbfilename dump.rdb
# Using Docker Compose
docker-compose up -d# Build locally
docker build -t redigo .
docker run -p 6379:6379 redigo# Using redis-cli
redis-cli -h localhost -p 6379
# Or using telnet
telnet localhost 6379# String operations
SET mykey "Hello World" PX 10000
GET mykey
INCR counter
# List operations
RPUSH mylist "item1" "item2" "item3"
LRANGE mylist 0 -1
LPOP mylist
# Sorted set operations
ZADD leaderboard 100 "player1" 200 "player2"
ZRANGE leaderboard 0 -1 WITHSCORES
ZRANK leaderboard "player1"
# Stream operations
XADD mystream * field1 value1 field2 value2
XRANGE mystream - +
XREAD STREAMS mystream 0-0
# Geospatial operations
GEOADD locations 13.361389 38.115556 "Palermo"
GEOADD locations 15.087269 37.502669 "Catania"
GEODIST locations "Palermo" "Catania" km
GEOSEARCH locations FROMLONLAT 15 37 BYRADIUS 200 km
# Pub/Sub
SUBSCRIBE news
PUBLISH news "Breaking news!"
# Transactions
MULTI
SET key1 value1
SET key2 value2
EXEC| Flag | Description | Default |
|---|---|---|
-port |
Server port | 6379 |
-replicaof |
Master server address (host port) | "" (master mode) |
-dir |
Directory for RDB file | "" |
-dbfilename |
RDB filename | "" |
- Concurrent-Safe - All operations use Go's sync primitives for thread safety
- RESP Protocol - Full implementation of Redis Serialization Protocol
- Non-Blocking I/O - Each connection handled in its own goroutine
- Master-Slave Replication - Command propagation with offset tracking
- Blocking Operations - Efficient blocking with Go channels and condition variables
- RDB Persistence - Binary format parsing with expiration support
The project builds a minimal Docker image using multi-stage builds:
- Builder stage: Compiles the Go application
- Runtime stage: Uses
scratchfor minimal image size (~10MB) - Publicly Available: seanxunx/redigo on Docker Hub
Pull the image:
docker pull seanxunx/redigo:latest# Install dependencies
go mod download
# Build
go build -o redigo ./app/
# Run tests (if available)
go test ./...This is a learning project built for CodeCrafters. Feel free to fork and experiment!
This project is open source and available for educational purposes.
Built as part of the CodeCrafters Redis Challenge - a hands-on way to learn how Redis works by building your own Redis server.
Made with β€οΈ and Go