đ Building RustyâŻKV â A Redis-Compatible, Secure KV Store in Rust


Author: Piush Bose
Repo: rusty-org/rusty-kv
CLI client: Included in the Releases on GitHub
đ Article Outline
Motivation & design philosophy
High-level architecture with diagrams
Detailed module walkthrough
Live code examples
How to get it running
Deep-dive: RESP parsing, auth, memory management
Next steps & contribution guide
1. Why RustâŻ&âŻRedis Compatibility?
Choosing Rust and speaking the Redis protocol were both deliberate decisions that unlock distinct advantagesâhereâs how they work together to make RustyâŻKV powerful, safe, and easy to adopt.
1.1 Rust: Safety, Speed, and Concurrency
Memory and Thread Safety
Rustâs ownership model and borrow checker eliminate entire classes of bugs at compile time: no nullâpointer dereferences, no useâafterâfree errors, and no data races. This means our core inâmemory engine can freely share state between threadsâunder the hood itâs allArc<âŚ>
andRwLock
, but you never have to write an unsafe line.ZeroâCost Abstractions
Highâlevel features like iterators, traits, and async/await compile down to highly optimized machine code. Rust gives you the expressiveness of modern languages without sacrificing performance; benchmarks often show it rivalingâor in some cases beatingâC or C++ on raw throughput.Asynchronous I/O with Tokio
Handling thousands of concurrent connections is straightforward with Tokioâs async runtime. We use nonâblocking sockets and a lightweight task scheduler so each client gets reactive, lowâlatency performance without spawning a thread per connection.
1.2 Redis RESP Protocol: Instant Ecosystem Compatibility
âSpeak Redis, Play Everywhereâ
RESP (Redis Serialization Protocol) is a simple, textâbased wire format that 200+ Redis clients already understand. By implementing RESP in RustyâŻKV, you can plug in any existing clientâPython, Go, JavaScriptâwithout writing new drivers or libraries.No Translation Layer
Rather than inventing our own protocol and adapter, we parse and emit the exact same messages Redis servers do. That means tools likeredis-cli
,redisâexporter
for Prometheus, and most orchestration scripts work out of the box.Minimal Overhead
RESPâs lineâoriented design is easy to parse in Rustâourresp
module reads byte buffers into aValue
enum in constant time per token. Likewise, serializing back is just patternâmatching on that enum. Thereâs virtually no CPU wasted on protocol gymnastics.
1.3 Secure MultiâTenancy: Ownership and Isolation
PerâUser Namespaces
Every successfulAUTH
call spins up a freshUserStore
instance, keyed by a cryptographic credential hash. That store is a scoped bucket for all subsequent commands, so Aliceâs keys can never collide with Bobâsâand one user canât read anotherâs data.Strong Password Hashing (Keccakâ256)
We never store plainâtext passwords. When you create or authenticate a user, we hash your password with Keccakâ256 (the same primitive underlying SHAâ3) before inserting or matching it in our SQLite credentials database.ThreadâSafe Isolation
Under the hood,MemoryStore
is anArc<RwLock<HashMap<CredHash, UserStore>>>
. Inside eachUserStore
, individualEntity
maps (HashMap, Set, etc.) are also wrapped inRwLock
. This layered locking strategy guarantees that two connections from the same user can safely interleave reads and writes, while connections for different users operate entirely on disjoint state.
By combining Rustâs guarantees with an industryâstandard wire protocol and robust multiâtenant design, RustyâŻKV delivers a productionâready keyâvalue store thatâs both highâperformance and secureâwithout forcing you to rewrite your tooling or compromise on safety.
2. Architecture at a Glance
Here's a visual breakdown of core components and data paths, powered by a standard Redisâstyle message flow:
sequenceDiagram
participant C as Client
participant S as RustyKV Server
C->>S: PING
S->>C: PONG
C->>S: SET key "value"
S->>C: OK
C->>S: GET key
S->>C: "value"
C->>S: DEL key
S->>C: 1
C->>S: HELP
S->>C: "Available commands: ..."
The authentication flow
flowchart TD
A[Client] -->|AUTH username password| B[Server]
B -->|Verify with SQLite| C[InternalDB]
C -->|Valid Credentials| D[Create UserStore]
D -->|Return OK| A
C -->|Invalid Credentials| E[Return Error]
E --> A
đŚ Memory Store Architecture
The MemoryStore
implements a sophisticated multi-user data isolation system:
Top Level:
MemoryStore
contains a map of user credential hashes toUserStore
instancesUser Level: Each
UserStore
contains named entities (data structures)Entity Level: Each entity is a specific data structure (HashMap, Set, LinkedList)
Data Level: The actual key-value pairs within each data structure
This layered approach provides:
Complete data isolation between users
Type-specific operations for different data needs
Thread-safety with
Arc
,Mutex
, andRwLock
primitivesNamespace organization with dot notation (e.g.,
hashmap.key
)
flowchart TD
MS[MemoryStore]
MS --> US1[UserStore: user1-hash]
MS --> US2[UserStore: user2-hash]
US1 --> E1[Entity: default]
US1 --> E2[Entity: users]
US1 --> E3[Entity: settings]
E1 --> HM1[HashMap]
E2 --> SET1[Set]
E3 --> LL1[LinkedList]
HM1 --> KV1[Key-Value Pairs]
SET1 --> V1[Unique Values]
LL1 --> V2[Ordered Values]
Key Components
TCP Listener (Tokio): handles client connections.
RESP Handler: parses incoming data into
Value
enums, serializes responses.Command Executor: dispatches commands like
GET
,SET
,AUTH
.MemoryStore: holds
UserStore
instances indexed by credential hash.UserStore: namespaceâscoped, threadâsafe storage of various entities (
HashMap
,Set
,LinkedList
).InternalDB: SQLiteâbased credentials management using
rusql
ite
, secure Keccakâ256 hashing.
⨠Features
RustyâŻKV Store is more than just GET/SET:
TCP server with async I/O (Tokio)
RESP protocol compatibility (all Redis clients work out of the box)
Command handling architecture
Inâmemory storage with async access
Implemented commands:
PING
â test connectivityECHO
â echo messagesSET
,GET
,DEL
â basic key operationsHELP
â list available commands
đď¸ SQLite Database Usage
Although all keyâvalue data is purely inâmemory, user credentials persist via SQLite:
Users table:
id
,username
,password
(Keccakâ256 hash),created_at
,updated_at
,root_user
Connection pooling: via
r2d2
Backup support: configurable intervals & paths
Autoâmigrates schema at startup
đ RESP Protocol Implementation
RESP (Redis Serialization Protocol) powers clientâserver messages:
Value types: SimpleString, BulkString, Integer, Boolean, Array, Null, Error
Parser: raw TCP â
Value
enumSerializer:
Value
â wire formatPerformance: constantâtime per token, zero-copy wherever possible
đ ď¸ Configuration Management
RustyâŻKV reads settings from a TOML file plus environment overrides:
Typed retrieval & dotânotation access
Defaults for network, database path, logging levels
Flexible for production or local dev
3. Module Walkthrough
a) resp module
Central to protocol handling:
pub enum Value {
SimpleString(String),
BulkString(String),
Integer(i64),
Boolean(bool),
Array(Vec<Value>),
Null,
Error(String),
}
Parser: uses byte-level scanning to convert raw TCP streams to
Value
.Serializer: circular signal generation per RESP spec.
b) auth module
Secure user login flow:
let hash = keccak256(&password);
let row = conn.query_row(
"SELECT id FROM users WHERE username = ?1 AND password = ?2",
params![username, hash],
|r| r.get(0))
- On success: generates a credential token, binds a
UserStore
to it, returns+OK
.
c) store module
Core in-memory engine:
struct MemoryStore {
inner: Arc<RwLock<HashMap<CredHash, UserStore>>>
}
UserStore
manages Entities by name usingRwLock<HashMap<_, Box<dyn Entity>>>
.Supports concurrent reads/writes safely via Rust sync primitives.
d) command_executor
Each command is implemented with type-preserving logic:
fn execute(&self, args: &[Value], user_store: &UserStore) -> Value { ... }
E.g., SET
stores a typed Value
, GET
retrieves it, and DEL
removes it. Type preservation avoids silent conversions.
4. Control Flow Diagram
flowchart LR
subgraph Network
AC[TCP AcceptConn] --> RH[RespHandler: parse/serialize]
end
RH --> CE[CommandExecutor]
CE --> ST[MemoryStore/Auth/InternalDB]
ST --> CE
CE --> RH --> Client
This illustrates how the system manages authentication, command dispatch, and storage access per connection.
5. Quickstart â Run it Yourself
git clone https://github.com/rusty-org/rusty-kv.git
cd rusty-kv
cargo run --release
Default server listens on 127.0.0.1:6379
. Use standard Redis CLI:
redis-cli
> AUTH alice hunter2
+OK
> SET foo "bar"
+OK
> GET foo
$3
bar
> PING
+PONG
The CLI client in Releases (rusty-kv-cli
) offers an enriched experience.
6. Deep-Dive Highlights
⢠6.1 RESP parsing
RESP handling lives in resp/mod.rs
. Each command is parsed in constant time, using pattern matches per RESP spec.
⢠6.2 Auth & Credential Hashing
Passwords are never stored plainâKeccak256
is applied before SQLite storage. Connection attempts without AUTH
return errors.
⢠6.3 Memory Isolation
Each user gets a private store. Access between users is impossible:
let map = store.inner.read().unwrap();
let user_store = map.get(&cred_hash).unwrap();
This ensures tenant data isolation.
⢠6.4 Type-Preserving Pipeline
Unlike Python or JS, Rustâs Value
enum retains types end-to-end. Conversion to string only for backward compatibility.
match value {
Value::Integer(i) => BulkString(i.to_string()),
âŚ
}
7. Whatâs Next?
â Planned Persistence: Snapshotting
.kdb
files plusKDB SAVE / LOAD
commands.â Additional Entities: e.g., Sorted Set, Stream.
â CLI Enhancements: Built-in tab-completion, logging verbosity.
â Benchmarks: Compare performance vs Redis under concurrent load.
đ˘ Call to Action
This project exemplifies Rustâs capabilities in systems programming, secure storage, and protocol design. Youâre invited to:
đ Explore the code on rusty-org/rusty-kv
đ ď¸ Tackle open issues and roadmap items in
TODO.md
â Star, fork, and spread the word!
Subscribe to my newsletter
Read articles from Piush Bose directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by

Piush Bose
Piush Bose
As Domain Lead for Cloud & DevOps at Techno India University, I bridge academic theory with industry standards, driving initiatives that turn classroom concepts into scalable solutions. Previously, as a Full Stack Developer at The Entrepreneurship Network, I delivered robust web solutions, showcasing my Kubernetes and DevOps expertise to meet and exceed business objectives.