A Redis server implementation written from scratch in Rust using Tokio. This project implements a subset of Redis's functionality, focusing on core commands, data structures, replication, and pub/sub. This project was built as part of the Build your own Redis.
redis-demo-compressed.mp4
- Built with Tokio for async I/O and runtime
- Supports concurrent client connections (up to 10,000)
- Implements master-replica replication with PSYNC and RDB snapshots
- Pub/Sub messaging with channel-based communication
- Transaction support with command queueing
- RDB file persistence with expiry support
- Rate Limit to max 10,000 concurrent connections
- String:
SET,GET,INCR - List:
LPUSH,RPUSH,LRANGE,LLEN,LPOP,BLPOP - Stream:
XADD,XRANGE,XREAD - Sorted Set:
ZADD,ZRANK,ZRANGE,ZCARD,ZSCORE,ZREM - Geospatial:
GEOADD,GEOPOS,GEODIST,GEOSEARCH - Transactions:
MULTI,EXEC,DISCARD - Pub/Sub:
SUBSCRIBE,UNSUBSCRIBE,PUBLISH - Connection:
PING,ECHO,AUTH - Server:
INFO,TYPE,WAIT,CONFIG,KEYS - ACL:
ACL WHOAMI,ACL GETUSER - Replication:
REPLCONF,PSYNC(master-slave replication)
- Bind to a port
- Respond to PING
- Respond to multiple PINGs
- Handle concurrent clients
- Implement the ECHO command
- Implement the SET & GET commands
- Expiry
- Create a list
- Append an element (RPUSH)
- Append multiple elements
- List elements with positive indexes (LRANGE)
- List elements with negative indexes
- Prepend elements (LPUSH)
- Query list length (LLEN)
- Remove an element (LPOP)
- Remove multiple elements
- Blocking retrieval (BLPOP)
- Blocking retrieval with timeout
- The TYPE command
- Create a stream (XADD)
- Validating entry IDs
- Partially auto-generated IDs
- Fully auto-generated IDs
- Query entries from stream (XRANGE)
- Query with
- - Query with
+ - Query single stream using XREAD
- Query multiple streams using XREAD
- Blocking reads
- Blocking reads without timeout
- Blocking reads using
$
- The INCR command
- The MULTI command
- The EXEC command
- Empty transaction
- Queueing commands
- Executing a transaction
- The DISCARD command
- Failures within transactions
- Multiple transactions
- Configure listening port
- The INFO command
- The INFO command on a replica
- Initial replication ID and offset
- Send handshake (REPLCONF, PSYNC)
- Receive handshake
- Empty RDB transfer
- Single-replica propagation
- Multi-replica propagation
- Command processing
- ACKs with no commands
- ACKs with commands
- WAIT with no replicas
- WAIT with no commands
- WAIT with multiple commands
- Subscribe to a channel
- Subscribe to multiple channels
- Enter subscribed mode
- PING in subscribed mode
- Publish a message
- Deliver messages
- Unsubscribe
- Respond to ACL WHOAMI
- Respond to ACL GETUSER
- The nopass flag
- The passwords property
- Setting default user password
- The AUTH command
- Enforce authentication
- Authenticate using AUTH
- RDB file config
- Read a key
- Read a string value
- Read multiple keys
- Read multiple string values
- Read value with expiry
- Create a sorted set
- Add members
- Retrieve member rank
- List sorted set members
- ZRANGE with negative indexes
- Count sorted set members
- Retrieve member score
- Remove a member
- Respond to GEOADD
- Validate coordinates
- Store a location
- Calculate location score
- Respond to GEOPOS
- Decode coordinates
- Calculate distance
- Search within radius
- Rust 1.70 or higher
- Cargo (comes with Rust)
To build the server, clone the repository and run:
cargo build --releaseRun the server using:
cargo run --release -- [--port <port>] [--replicaof <master_host> <master_port>]Or run the pre-built binary:
./target/release/codecrafters-redis [--port <port>] [--replicaof <master_host> <master_port>]Options:
--port: The port to listen on (default:6379)--replicaof: Configure as a replica of the specified master (format:<host> <port>)
Examples:
# Run as master on default port 6379
cargo run --release
# Run as master on custom port
cargo run --release -- --port 6380
# Run as replica
cargo run --release -- --port 6380 --replicaof 127.0.0.1 6379Connect to the server using any Redis client such as redis-cli:
redis-cli -p 6379Once connected, you can use any of the supported commands:
SET mykey "Hello"
GET mykey
INCR counter
LPUSH mylist "item1" "item2"
XADD stream:1 * field1 value1
MULTI
SET key1 val1
SET key2 val2
EXEC
SUBSCRIBE channel1
PUBLISH channel1 "message"
The codebase has been refactored into a modular architecture for better maintainability and separation of concerns:
src/
├── main.rs # Server initialization and entry point
├── protocol/
│ ├── mod.rs # Protocol module exports
│ ├── state.rs # Redis state and server state management
│ ├── value.rs # RedisValue type definitions
│ └── replication.rs # Replication handshake and sync logic
├── commands/
│ ├── mod.rs # Command module exports
│ └── handler.rs # Command execution and routing
├── client/
│ ├── mod.rs # Client module exports
│ ├── normal_mode.rs # Standard client connection handling
│ ├── subscribe_mode.rs # Pub/Sub client connection handling
│ └── replica_mode.rs # Replica-to-master connection handling
└── utils.rs # RESP protocol encoding/decoding utilities
Key Modules:
protocol/- Core Redis protocol types, state management, and replication logiccommands/- Command parsing, validation, and executionclient/- Different client connection modes (normal, subscribe, replica)utils.rs- Low-level RESP protocol utilities and configuration
cargo run -- --port 6379To run tests install codecrafters cli:
curl https://codecrafters.io/install.sh | sh
codecrafters test