Sibling to the Python, Go, and Node.js workshops. Same architectural progression, idiomatic async Rust on the tokio runtime.
Status: All 10 modules complete. cargo build --release clean across the workspace.
| # | Step | New Rust idiom |
|---|---|---|
| 01 | TCP echo | tokio::net::TcpListener + tokio::spawn |
| 02 | RESP parser | Vec + cursor + enum sum type |
| 03 | GET / SET | Arc<Mutex> + tokio::sync::Mutex |
| 04 | Expiry | Instant + sidecar HashMap + saturating_duration |
| 05 | AOF persistence | tokio::fs append + Option<&AofFile> pattern |
| 06 | RDB snapshots | tokio::fs::write + tokio::fs::rename atomic |
| 07 | Pub/Sub | tokio::sync::broadcast + select! reader/writer |
| 08 | Replication | Master/replica via broadcast feed + SYNC |
| 09 | Graceful shutdown | tokio::signal + watch + semaphore drain |
| 10 | Capstone benchmark | RESP load generator + p50/p95/p99 |
Each step folder ships with:
| File | Purpose |
|---|---|
src/main.rs |
The runnable server |
Cargo.toml |
tokio dependency |
README.md |
Run instructions and what's new |
GUIDE.md |
Deep-dive on the Rust idiom |
EXERCISES.md |
4 hands-on tasks |
- Rust 1.75+ (
rustup install stable) - Cargo (comes with Rust)
- Optional:
redis-clifor talking to the server
git clone https://github.com/learnwithparam/build-your-own-redis-rust.git
cd build-your-own-redis-rust
make 01-tcp-echoIn another terminal:
nc localhost 6380
> hello
< hellomake 01-tcp-echo
make 02-resp-parser
make 03-get-set
make 04-expiry
make 05-aof-persistence
make 06-rdb-snapshots
make 07-pubsub
make 08-replication # masters on 6380; replica with: cargo run --release --bin step08-replication -- replica 127.0.0.1:6381 127.0.0.1:6380
make 09-graceful-shutdown
make 10-capstone # benchmark vs real Redis on 6379Rust closes most of the gap to real Redis (C) while keeping memory safety. The architecture is identical to the Python and Go siblings; the constant factor is the language.
- No GC pauses: throughput is more predictable than Go or Node
- Sum types via enum: protocol parsers are bulletproof, the compiler enforces case coverage
- Ownership model: shared mutable state needs Arc + Mutex (or RwLock or DashMap); the choice is explicit
- async/await on tokio: per-connection tasks are cheap, the runtime scheduler is excellent
Same architecture in other languages:
| Concept | Python | Go | Node | Rust |
|---|---|---|---|---|
| Concurrency | Threads or selectors | Goroutines | Event loop | tokio tasks |
| Shared state | dict + lock | sync.RWMutex | Map (no lock) | Arc<Mutex> |
| Tool for absence | None | nil | null | Option |
| Sum type | duck typing | interface{} | discriminated objects | enum |
MIT.