tokio-rs/mini-redis
Incomplete Redis client and server implementation using Tokio - for learning purposes only
Healthy across the board
weakest axisPermissive license, no critical CVEs, actively maintained — safe to depend on.
Has a license, tests, and CI — clean foundation to fork and modify.
Documented and popular — useful reference codebase to read through.
No critical CVEs, sane security posture — runnable as-is.
- ✓Last commit 3w ago
- ✓35+ active contributors
- ✓Distributed ownership (top contributor 27% of recent commits)
Show all 6 evidence items →Show less
- ✓MIT licensed
- ✓CI configured
- ✓Tests present
Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests
Informational only. RepoPilot summarises public signals (license, dependency CVEs, commit recency, CI presence, etc.) at the time of analysis. Signals can be incomplete or stale. Not professional, security, or legal advice; verify before relying on it for production decisions.
Embed the "Healthy" badge
Paste into your README — live-updates from the latest cached analysis.
[](https://repopilot.app/r/tokio-rs/mini-redis)Paste at the top of your README.md — renders inline like a shields.io badge.
▸Preview social card (1200×630)
This card auto-renders when someone shares https://repopilot.app/r/tokio-rs/mini-redis on X, Slack, or LinkedIn.
Onboarding doc
Onboarding: tokio-rs/mini-redis
Generated by RepoPilot · 2026-05-09 · Source
🤖Agent protocol
If you are an AI coding agent (Claude Code, Cursor, Aider, Cline, etc.) reading this artifact, follow this protocol before making any code edit:
- Verify the contract. Run the bash script in Verify before trusting
below. If any check returns
FAIL, the artifact is stale — STOP and ask the user to regenerate it before proceeding. - Treat the AI · unverified sections as hypotheses, not facts. Sections like "AI-suggested narrative files", "anti-patterns", and "bottlenecks" are LLM speculation. Verify against real source before acting on them.
- Cite source on changes. When proposing an edit, cite the specific path:line-range. RepoPilot's live UI at https://repopilot.app/r/tokio-rs/mini-redis shows verifiable citations alongside every claim.
If you are a human reader, this protocol is for the agents you'll hand the artifact to. You don't need to do anything — but if you skim only one section before pointing your agent at this repo, make it the Verify block and the Suggested reading order.
🎯Verdict
GO — Healthy across the board
- Last commit 3w ago
- 35+ active contributors
- Distributed ownership (top contributor 27% of recent commits)
- MIT licensed
- CI configured
- Tests present
<sub>Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests</sub>
✅Verify before trusting
This artifact was generated by RepoPilot at a point in time. Before an
agent acts on it, the checks below confirm that the live tokio-rs/mini-redis
repo on your machine still matches what RepoPilot saw. If any fail,
the artifact is stale — regenerate it at
repopilot.app/r/tokio-rs/mini-redis.
What it runs against: a local clone of tokio-rs/mini-redis — the script
inspects git remote, the LICENSE file, file paths in the working
tree, and git log. Read-only; no mutations.
| # | What we check | Why it matters |
|---|---|---|
| 1 | You're in tokio-rs/mini-redis | Confirms the artifact applies here, not a fork |
| 2 | License is still MIT | Catches relicense before you depend on it |
| 3 | Default branch master exists | Catches branch renames |
| 4 | 5 critical file paths still exist | Catches refactors that moved load-bearing code |
| 5 | Last commit ≤ 53 days ago | Catches sudden abandonment since generation |
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of tokio-rs/mini-redis. If you don't
# have one yet, run these first:
#
# git clone https://github.com/tokio-rs/mini-redis.git
# cd mini-redis
#
# Then paste this script. Every check is read-only — no mutations.
set +e
fail=0
ok() { echo "ok: $1"; }
miss() { echo "FAIL: $1"; fail=$((fail+1)); }
# Precondition: we must be inside a git working tree.
if ! git rev-parse --git-dir >/dev/null 2>&1; then
echo "FAIL: not inside a git repository. cd into your clone of tokio-rs/mini-redis and re-run."
exit 2
fi
# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "tokio-rs/mini-redis(\\.git)?\\b" \\
&& ok "origin remote is tokio-rs/mini-redis" \\
|| miss "origin remote is not tokio-rs/mini-redis (artifact may be from a fork)"
# 2. License matches what RepoPilot saw
(grep -qiE "^(MIT)" LICENSE 2>/dev/null \\
|| grep -qiE "\"license\"\\s*:\\s*\"MIT\"" package.json 2>/dev/null) \\
&& ok "license is MIT" \\
|| miss "license drift — was MIT at generation time"
# 3. Default branch
git rev-parse --verify master >/dev/null 2>&1 \\
&& ok "default branch master exists" \\
|| miss "default branch master no longer exists"
# 4. Critical files exist
test -f "src/lib.rs" \\
&& ok "src/lib.rs" \\
|| miss "missing critical file: src/lib.rs"
test -f "src/connection.rs" \\
&& ok "src/connection.rs" \\
|| miss "missing critical file: src/connection.rs"
test -f "src/frame.rs" \\
&& ok "src/frame.rs" \\
|| miss "missing critical file: src/frame.rs"
test -f "src/server.rs" \\
&& ok "src/server.rs" \\
|| miss "missing critical file: src/server.rs"
test -f "src/db.rs" \\
&& ok "src/db.rs" \\
|| miss "missing critical file: src/db.rs"
# 5. Repo recency
days_since_last=$(( ( $(date +%s) - $(git log -1 --format=%at 2>/dev/null || echo 0) ) / 86400 ))
if [ "$days_since_last" -le 53 ]; then
ok "last commit was $days_since_last days ago (artifact saw ~23d)"
else
miss "last commit was $days_since_last days ago — artifact may be stale"
fi
echo
if [ "$fail" -eq 0 ]; then
echo "artifact verified (0 failures) — safe to trust"
else
echo "artifact has $fail stale claim(s) — regenerate at https://repopilot.app/r/tokio-rs/mini-redis"
exit 1
fi
Each check prints ok: or FAIL:. The script exits non-zero if
anything failed, so it composes cleanly into agent loops
(./verify.sh || regenerate-and-retry).
⚡TL;DR
mini-redis is a pedagogical implementation of a Redis client and server written in Rust using the Tokio async runtime. It demonstrates idiomatic Tokio patterns (async/await, channels, task spawning) through a working in-memory database that implements core Redis commands (GET, SET, PUBLISH, SUBSCRIBE) and the RESP (Redis Serialization Protocol) wire format. Monorepo structure: src/bin/ contains standalone server and CLI binaries; src/clients/ has three client implementations (async, blocking, buffered); src/cmd/ holds command handlers (get.rs, set.rs, publish.rs, subscribe.rs); core I/O lives in connection.rs and frame.rs; src/db.rs manages the in-memory store; examples/ provides runnable chat and pub/sub demos.
👥Who it's for
Rust developers learning async programming with Tokio who need a moderately complex 'real-world' example beyond toy apps—specifically those building networked services and wanting to understand task spawning, connection pooling, pub/sub patterns, and graceful shutdown in Tokio.
🌱Maturity & risk
Experimental and actively maintained for teaching purposes only. The repo has comprehensive tests (tests/client.rs, tests/server.rs, tests/frame_validation.rs), a GitHub Actions CI pipeline (.github/workflows/ci.yml), and clear MIT licensing, but carries an explicit disclaimer not to use in production. It deliberately omits Redis protocol completeness to remain pedagogically focused.
Low risk as a learning resource, but explicitly unsupported for production use. The codebase is intentionally incomplete (pub/sub, blocking client, buffered client exist but full Redis compatibility is out of scope). Dependencies are stable and few (tokio, bytes, tracing, clap); the single-maintainer model (Carl Lerche) is mitigated by Tokio organization backing. No breaking changes expected since the feature set is frozen by design.
Active areas of work
No active development visible in provided data—this is a stable, frozen learning resource. The OpenTelemetry integration (otel feature) is present but optional, suggesting past exploration of observability patterns. CI via GitHub Actions runs on all commits.
🚀Get running
git clone https://github.com/tokio-rs/mini-redis.git
cd mini-redis
RUST_LOG=debug cargo run --bin mini-redis-server
# In another terminal:
cargo run --example hello_world
# Or use the CLI:
cargo run --bin mini-redis-cli set foo bar
cargo run --bin mini-redis-cli get foo
Daily commands:
Start server: RUST_LOG=debug cargo run --bin mini-redis-server. Start client example: cargo run --example hello_world. Run tests: cargo test. Run CLI client: cargo run --bin mini-redis-cli set key value.
🗺️Map of the codebase
src/lib.rs— Library root exposing all public APIs (Client, BlockingClient, Frame, Command types); essential entry point for understanding module hierarchysrc/connection.rs— Core async I/O abstraction managing TCP read/write with frame encoding/decoding; all client-server communication flows through thissrc/frame.rs— Redis RESP protocol parser and serializer; handles binary frame format that all commands depend onsrc/server.rs— Async server loop accepting connections and dispatching to command handlers; demonstrates Tokio task spawning patternssrc/db.rs— In-memory key-value store with Arc<Mutex<>> shared state; shows concurrent access patterns for Tokio applicationssrc/clients/client.rs— Async Redis client implementation using Connection abstraction; primary user-facing API demonstrating async/await usagesrc/cmd/mod.rs— Command parsing and dispatch logic; router determining which command handlers execute
🛠️How to make changes
Add a new Redis command
- Create handler file in src/cmd/ following naming convention (e.g., src/cmd/incr.rs) with public execute() function (
src/cmd/incr.rs) - Define Command enum variant in src/cmd/mod.rs and add parsing case in impl Command::from_frame() (
src/cmd/mod.rs) - Add dispatch case in Command::apply() to call execute() and return Frame response (
src/cmd/mod.rs) - Add client method in src/clients/client.rs wrapping the new command (e.g., incr(&mut self, key: &str) -> Result<i64>) (
src/clients/client.rs) - Write integration test in tests/client.rs validating command parsing and execution (
tests/client.rs)
Add a new client variant
- Create new struct in src/clients/ (e.g., src/clients/batch_client.rs) implementing desired semantics around Connection (
src/clients/batch_client.rs) - Implement public command methods (get, set, etc.) delegating to underlying Connection (
src/clients/batch_client.rs) - Export from src/clients/mod.rs as public type (
src/clients/mod.rs) - Add integration tests in tests/ directory validating client behavior (
tests/batch_client.rs)
Modify RESP protocol handling
- Update Frame enum in src/frame.rs to add variant or change serialization (
src/frame.rs) - Update parser in src/parse.rs to handle new binary format or edge cases (
src/parse.rs) - Update Connection read/write in src/connection.rs if frame boundary detection changes (
src/connection.rs) - Add test cases to tests/frame_validation.rs validating new format round-trips (
tests/frame_validation.rs)
Add pub/sub feature extension
- Extend src/db.rs to add broadcast channels map for topic subscriptions (
src/db.rs) - Implement subscription state tracking in src/cmd/subscribe.rs (uses async-stream for streaming responses) (
src/cmd/subscribe.rs) - Ensure Connection in src/connection.rs supports long-lived subscriptions (non-terminating streams) (
src/connection.rs) - Add integration test in tests/server.rs testing multi-client pub/sub flows (
tests/server.rs)
🔧Why these technologies
- Tokio — Async runtime enabling thousands of concurrent TCP connections; primary learning target of the project
- bytes crate — Zero-copy buffer management for RESP frame serialization/deserialization; efficient network I/O
- async-stream — Generator-like syntax for streaming responses (SUBSCRIBE command); simplifies async iteration logic
- Arc<Mutex<>> — Shared mutable in-memory database; demonstrates Tokio-safe concurrency patterns (not std::sync::Mutex)
- tracing — Structured logging and observability; common Tokio ecosystem pattern for debugging async code
⚖️Trade-offs already made
-
Single-threaded async executor with Arc<Mutex<>> vs. sharded locks or parking_lot
- Why: Simplicity for educational purposes; Tokio single-threaded runtime with Arc<Mutex<>> is sufficient for demo load
- Consequence: Lock contention under high concurrency; not production-ready but clearly demonstrates the problem
-
Incomplete Redis protocol (subset of commands, no persistence, no replication)
- Why: Scope reduction for learning Tokio patterns; full Redis would obscure async fundamentals
- Consequence: Cannot be used as production Redis; users must understand it is intentionally incomplete
-
Blocking client wrapper around async client vs. separate blocking implementation
- Why: Code reuse and maintainability; single async implementation + blocking wrapper is cleaner than duplication
- Consequence: BlockingClient spawns a runtime internally, slightly higher overhead than native blocking code
-
In-memory only storage with no expiration/TTL
- Why: Reduces implementation complexity; teaches core async patterns without db internals
- Consequence: All SET commands are permanent; missing fundamental Redis feature but not critical for learning
🚫Non-goals (don't propose these)
- Production-ready Redis implementation (explicitly labeled as incomplete learning resource)
- Persistence or durability (no RDB/AOF)
- Cluster support or replication
- Full Redis command set (subset only)
- Authentication or TLS
- Transactions or ACID guarantees
- Memory limits or eviction policies
- Pipelining optimization
- Performance at scale (educational, not optimized)
🪤Traps & gotchas
No external services required, but RUST_LOG env var must be set to see debug logs (defaults to no logging). OpenTelemetry feature (otel) requires optional deps and AWS OTel Collector running separately if enabled—only for observability demos. The buffered_client and blocking_client are incomplete/partial implementations (see src/clients/buffered_client.rs limitations). Frame reading on connection.rs can block on network I/O; understand backpressure semantics if modifying.
🏗️Architecture
💡Concepts to learn
- RESP (Redis Serialization Protocol) — Understanding RESP is essential to implementing frame.rs and parse.rs; it's a simple text-based protocol with specific serialization rules that learners must parse correctly
- Graceful Shutdown with Broadcast Channels — shutdown.rs demonstrates the broadcast channel pattern to signal all spawned tasks to shut down cleanly; critical pattern for production async services
- Per-Connection Task Spawning — server.rs spawns a new Tokio task per client connection; learners must understand task isolation, ownership transfer with move closures, and backpressure implications
- Shared Mutable State with Arc<Mutex<>> — db.rs uses Arc<Mutex<HashMap>> to allow multiple async tasks safe concurrent access to the in-memory store; demonstrates async-aware locking patterns
- Pub/Sub Pattern with tokio::sync Channels — cmd/subscribe.rs and cmd/publish.rs show how to implement a publish-subscribe system using Tokio's broadcast and mpsc channels across distributed tasks
- Buffering and Backpressure — connection.rs must handle partial reads/writes and frame boundaries over TcpStream; understanding buffering prevents data loss and resource exhaustion
- Command Dispatcher Pattern — cmd/mod.rs shows how to route different command types to handlers at runtime; teaches trait objects and enum dispatch patterns useful beyond Redis
🔗Related repos
tokio-rs/tokio— Parent project providing the Tokio async runtime that mini-redis is built entirely on top oftokio-rs/tracing— Instrumentation library used throughout mini-redis for structured logging and optional OpenTelemetry exportredis-rs/redis-rs— Full-featured production Redis client library for Rust; shows what a complete implementation looks like beyond mini-redis's pedagogical scopeantirez/redis— Official Redis source code; mini-redis implements a small subset of Redis semantics and wire protocol documented heretokio-rs/tokio-tutorial— Official Tokio tutorial materials; mini-redis serves as a capstone project demonstrating all patterns taught in the tutorial
🪄PR ideas
To work on one of these in Claude Code or Cursor, paste:
Implement the "<title>" PR idea from CLAUDE.md, working through the checklist as the task list.
Add comprehensive tests for src/cmd/subscribe.rs and src/cmd/publish.rs
The pub/sub functionality is a core Redis feature with examples (examples/pub.rs, examples/sub.rs) but lacks dedicated unit tests. Currently only examples/chat.rs demonstrates pub/sub, and tests/server.rs likely doesn't cover subscription edge cases like multiple subscribers, unsubscribe behavior, or message ordering. This is critical because pub/sub involves concurrent client handling and state management.
- [ ] Create tests/pubsub.rs to test publish/subscribe command interactions
- [ ] Add tests for multiple concurrent subscribers receiving messages
- [ ] Add tests for unsubscribe behavior and cleanup
- [ ] Add tests for edge cases: publishing with no subscribers, subscribing then disconnecting
- [ ] Verify message ordering across multiple publishers/subscribers
Add connection pooling and reconnection logic to src/clients/client.rs
The current async client in src/clients/client.rs appears to be a single-connection implementation. Real-world applications need connection pooling and automatic reconnection on transient failures. This would demonstrate important Tokio patterns (Arc, Mutex, exponential backoff) and make the library more production-ready for learning purposes.
- [ ] Design a ClientPool struct wrapping multiple Client instances
- [ ] Implement connection health checking in src/clients/client.rs
- [ ] Add exponential backoff reconnection logic for dropped connections
- [ ] Add integration tests in tests/client.rs for pool behavior under connection failures
- [ ] Document pool usage patterns in examples/hello_world.rs or new example
Add OpenTelemetry instrumentation to src/cmd/mod.rs and src/server.rs
The Cargo.toml already has optional otel dependencies defined but they appear unused throughout the codebase. Adding actual instrumentation (spans for command execution, metrics for request latency) would demonstrate observability patterns in Tokio applications and make the optional 'otel' feature meaningful.
- [ ] Add span creation in src/cmd/mod.rs Process::execute() for each command type
- [ ] Add span creation in src/server.rs for connection handling and request processing
- [ ] Add metrics tracking (latency histograms) for GET/SET/PUBLISH/SUBSCRIBE commands
- [ ] Create examples/otel.rs demonstrating OTLP export configuration
- [ ] Add tests/otel_integration.rs to verify spans are correctly generated under the 'otel' feature
🌿Good first issues
- Add DELETE command: create src/cmd/delete.rs following the pattern of src/cmd/get.rs (parse args, mutate db, return response), add unit test in same file, register in src/cmd/mod.rs dispatcher.
- Complete buffered_client.rs: it currently has stubs for pipelined operations; implement internal write buffer and flush logic following patterns in src/clients/client.rs to allow batching multiple commands.
- Add RESP protocol validation tests: src/frame.rs parses frames but lacks explicit tests for malformed RESP input (overflow integers, invalid types, truncated messages)—add property-based tests to tests/frame_validation.rs.
⭐Top contributors
Click to expand
Top contributors
- @carllerche — 27 commits
- @Darksonn — 10 commits
- @tottoto — 8 commits
- @jxs — 8 commits
- @Sunt-ing — 7 commits
📝Recent commits
Click to expand
Recent commits
3d93b42— Validate NULL bulk strings have expected format (#157) (Dailiduzhou)7295d72— Fix set expire (replace push_integer by push_bulk) (#116) (YunoL)5948f07— Add macos and windows to CI (#153) (jayvdb)6bd70b3— Fix clippy lint needless_doctest_main (#152) (jayvdb)5c10308— Move args into format strings (#151) (jayvdb)8ca8bbe— Fix publish command name in subscribe errors (#156) (vonbai)e186482— Remove unnecessary custom clap value parser (#147) (tottoto)b63a489— Update clap deprecated api (#132) (tottoto)c2b18b9— Fix typos (#145) (jayvdb)ab7353b— Update db.rs (#143) (bn-l)
🔒Security observations
This is an educational project explicitly not intended for production use. The codebase has several medium-severity concerns typical of learning implementations: incomplete protocol handling, missing authentication framework, no visible encryption/TLS support, and lack of input validation documentation. The primary security posture is undermined by the incomplete nature of the project. For legitimate use, a fully-featured production Redis client should be used instead. If extending this codebase for learning, the recommendations should be followed to understand security best practices.
- Medium · Incomplete Redis Protocol Implementation —
README.md, src/ (overall architecture). The codebase explicitly states it is an 'incomplete' implementation of Redis. This means not all Redis protocol features are implemented, which could lead to unexpected behavior, command injection vulnerabilities, or unhandled edge cases in production-like scenarios. The project documentation warns against production use. Fix: This project is explicitly designed for learning only. Do not use in production. For production use, switch to fully-featured Redis client/server libraries. If extending this codebase, conduct thorough security reviews of any new protocol handling code. - Medium · No Input Validation Framework Evident —
src/parse.rs, src/frame.rs, src/connection.rs. The codebase includes a parser (src/parse.rs) and frame handling (src/frame.rs), but without reviewing the actual implementation, there's risk of improper input validation. Redis protocol parsing could be vulnerable to malformed or malicious input if not properly validated. Fix: Implement strict input validation for all Redis protocol parsing. Validate frame boundaries, command lengths, and argument types. Use safe parsing libraries and implement fuzzing tests to verify robustness against malformed input. - Medium · Pub/Sub Implementation Security —
src/cmd/publish.rs, src/cmd/subscribe.rs, src/server.rs. The codebase includes pub/sub functionality (src/cmd/subscribe.rs, src/cmd/publish.rs). Without access to the implementation details, there's potential for security issues such as: message injection, privilege escalation via subscription patterns, or denial of service through unbounded subscriptions. Fix: Implement rate limiting on publish and subscribe operations. Validate subscription patterns to prevent regex DoS attacks. Implement per-client subscription limits. Add authentication checks for sensitive channels. - Medium · No Visible Authentication Mechanism —
src/bin/server.rs, src/clients/. The repository structure shows client and server implementations but no obvious authentication module or token-based access control. Redis by default has weak authentication (optional AUTH command), and this implementation may lack even basic credential verification. Fix: Implement proper authentication mechanism. Add AUTH command support with secure password hashing. Consider token-based authentication. Restrict server access to authenticated clients only. Document security model clearly. - Low · Tracing Configuration Exposure —
src/ (application startup), Cargo.toml. The project uses tracing with env-filter capability (tracing-subscriber with env-filter feature). If misconfigured, verbose logging could expose sensitive data like command arguments, keys, or values through debug output. Fix: Configure tracing to avoid logging sensitive command data. Use structured logging with field redaction for sensitive values. Set appropriate logging levels for production. Document logging configuration security guidelines. - Low · No Visible TLS/Encryption Support —
src/connection.rs, src/bin/server.rs. The codebase does not show TLS support in the visible structure. Communications between clients and server appear to be in plaintext, making them vulnerable to man-in-the-middle attacks. Fix: Add TLS support using tokio-native-tls or tokio-rustls. Make TLS mandatory for production deployments. Implement certificate validation. Consider supporting only TLS 1.2+. - Low · Dependency on 'full' Tokio Feature Set —
Cargo.toml (dependencies). Cargo.toml includes tokio with 'full' features in both main and dev dependencies. This significantly increases the attack surface by including unnecessary features and dependencies that could have vulnerabilities. Fix: Replace 'full' feature set with explicit minimal required features. Review tokio documentation to identify essential features only (likely: io-util, net, rt, sync, time). This reduces dependency footprint and potential vulnerabilities.
LLM-derived; treat as a starting point, not a security audit.
👉Where to read next
- Open issues — current backlog
- Recent PRs — what's actively shipping
- Source on GitHub
Generated by RepoPilot. Verdict based on maintenance signals — see the live page for receipts. Re-run on a new commit to refresh.