CLI tool
tokio-rs/mini-redis avatar
tokio-rs/mini-redis

mini-redis: An Idiomatic Tokio Application for Learning Async Rust

Incomplete Redis client and server implementation using Tokio - for learning purposes only

4,788 stars583 forksRustMIT

At a glance

What is it?
mini-redis is an incomplete Redis client and server implementation in Rust, built by the Tokio team as a teaching resource. It demonstrates async patterns including TCP serving, pub/sub, graceful shutdown, and connection limiting within a real-world problem that is familiar enough to understand quickly.
Who is it for?
mini-redis is the right resource for Rust developers who want to learn how to build a production-style async application with Tokio and need a project with enough complexity to be educational. It is not a substitute for a real Redis client: the README is explicit that it omits many Redis protocol features and will not add new ones.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 168 days ago.
What is it written in?
Mainly Rust, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 27, 2026, and from our analysis. They are not legal advice.

Editorial analysis

What mini-redis is and why it uses Redis as the subject

mini-redis is an incomplete, idiomatic implementation of a Redis client and server built with Tokio. The Tokio team created it to serve as a larger example of writing a Tokio application. Redis was chosen for this purpose because it combines a wide range of features with a simple wire protocol. That combination lets the project demonstrate many async Rust patterns in a context that feels real rather than contrived.

The README is direct about what the project is not: a production Redis implementation. It states that features are omitted not because of difficulty but because implementing them would not introduce new concepts. The project intentionally leaves out persistence, cluster support, and most Redis commands. The README lists five supported commands: PING, GET, SET, PUBLISH, and SUBSCRIBE.

For anyone who needs a production-ready Redis client in Rust, the redis crate on crates.io is the established option. mini-redis is for learning the patterns, not for building services.

Tokio patterns the project demonstrates

The README names several specific async programming patterns visible in the codebase. The TCP server in `src/server.rs` accepts connections and spawns a new task per connection using `tokio::spawn`. The server handles `accept` errors gracefully rather than panicking, which is the correct behavior for a long-running server process.

Shared state is handled in `src/db.rs` through a `Db` struct accessible from all connections. The README makes a deliberate choice to use `std::sync::Mutex` rather than a Tokio mutex for this purpose. This is intentional and documented: a `std::sync::Mutex` is appropriate when the lock is held only in synchronous code, which is the case here. Using a Tokio mutex unnecessarily would be incorrect advice for new Tokio users.

The wire protocol is modeled in `src/connection.rs` and `src/frame.rs` using an intermediate `Frame` representation. The `Connection` struct wraps a `TcpStream` and exposes an API for sending and receiving frames. This separation between protocol framing and connection handling is a pattern the README highlights as idiomatic.

Graceful shutdown uses `tokio::signal` to listen for SIGINT. On receipt, the server stops accepting new connections and notifies existing connections to complete their current work before closing. Concurrent connection limiting is implemented with a `Semaphore` from the Tokio synchronization primitives.

Running the server and client

The repository provides three executables. The server starts with:

code
RUST_LOG=debug cargo run --bin mini-redis-server

The `RUST_LOG=debug` environment variable sets the log level for the tracing subscriber. Log levels are controlled through the `tracing` crate's `EnvFilter` and can be changed by substituting `debug` with `info`, `warn`, or `error`.

With the server running, the example programs in the `examples/` directory demonstrate specific features. The hello_world example sends a SET followed by a GET:

code
cargo run --example hello_world

A command-line client is also provided. The following stores a value and retrieves it:

code
cargo run --bin mini-redis-cli set foo bar
cargo run --bin mini-redis-cli get foo

The `examples/` directory includes four examples: `hello_world.rs`, `chat.rs`, `pub.rs`, and `sub.rs`. The pub/sub examples demonstrate the publish and subscribe commands: `pub.rs` publishes a message to a channel, and `sub.rs` subscribes to that channel and prints incoming messages.

Pub/Sub implementation: broadcast channels and StreamMap

The pub/sub subsystem in mini-redis is more complex than the key-value store and demonstrates several Tokio patterns not visible in simpler examples. The server implements pub/sub by creating one broadcast channel per topic. When a client subscribes to a topic, it receives a receiver for that broadcast channel. When any publisher sends a message to the topic, all current receivers receive it.

A connection may subscribe to multiple channels simultaneously and update its subscriptions at any time by sending additional SUBSCRIBE commands. The README explains that this is handled using a `StreamMap` per connection. `StreamMap` from the `tokio-stream` crate merges multiple async streams into one, polling all of them and yielding the next item from whichever resolves first.

The README notes that a client subscribed to many channels efficiently waits for messages from any of them without spawning a separate task per channel. This is a practical pattern for multiplexed async I/O that generalizes beyond Redis to any system where a single connection must listen to multiple event sources.

OpenTelemetry integration and distributed tracing

The README includes a section on OpenTelemetry that is relevant for developers building cloud services. When running many instances of an application, traces from all instances need to be collected into a centralized backend for analysis. mini-redis supports sending traces to AWS X-Ray using an optional `otel` feature flag.

Enabling the feature switches the tracing instrumentation from the local subscriber to OpenTelemetry:

code
RUST_LOG=debug cargo run --bin mini-redis-server --features otel

This requires an AWS OTel Collector running on the same host. The README links to a Docker-based demo setup for the collector. The `otel` feature adds three optional dependencies: `opentelemetry`, `tracing-opentelemetry`, and `opentelemetry-aws` for X-Ray propagation, plus `opentelemetry-otlp` for the OTLP exporter.

This section is primarily useful to developers who are building distributed services and need to understand how to integrate Tokio applications with observability infrastructure. The X-Ray example is one specific backend; the OpenTelemetry standard allows switching backends without changing application code.

Testing async time-dependent behavior

The test suite in `tests/server.rs` includes tests for key expiration, which requires simulating time passing. The README notes that mini-redis uses Tokio's testing utilities to mock time rather than depending on wall-clock delays. Tests that depend on `sleep` or `timeout` with real time are slow and non-deterministic. Tokio's `time::pause` and `time::advance` allow tests to skip ahead in simulated time without waiting.

The `tokio` dev dependency in `Cargo.toml` includes the `test-util` feature specifically for this:

code
[dev-dependencies]
tokio = { version = "1", features = ["test-util"] }

This is a pattern that every async Rust project with time-dependent behavior should adopt. mini-redis demonstrates it at the integration test level, where the behavior being tested involves the full server rather than individual units.

The repository was last pushed on 2026-04-15. It has no GitHub releases but the Cargo.toml lists version 0.4.1. The project is licensed under the MIT license, and the README states that contributions are welcome if they introduce new Tokio patterns rather than adding Redis features.

Editorial conclusion

mini-redis is the right resource for Rust developers who want to learn how to build a production-style async application with Tokio and need a project with enough complexity to be educational. It is not a substitute for a real Redis client: the README is explicit that it omits many Redis protocol features and will not add new ones. For production Redis access from Rust, use the redis crate instead. Before starting with mini-redis, confirm you have Rust and Cargo installed, clone the repository, and begin with the examples directory after reading the README's patterns section.

Frequently asked questions

What is mini-redis?

Mini-redis is an incomplete Redis client and server implementation written in Rust using the Tokio async runtime. The Tokio team built it as a teaching resource demonstrating async patterns including TCP serving, pub/sub, graceful shutdown, and connection limiting. It is not intended for production use.

What Rust async patterns does mini-redis demonstrate?

The README lists TCP server task spawning, shared state with std::sync::Mutex, wire protocol framing with an intermediate Frame type, graceful shutdown via tokio::signal, connection limiting with Semaphore, pub/sub using broadcast channels and StreamMap, and testing time-dependent code with Tokio's test-util.

Can mini-redis replace Redis in a production Rust application?

The README explicitly says no. It omits most Redis commands and states that new features will not be added to serve production needs. For production Redis access from Rust, the README advises using a fully featured alternative.

Official sources

  1. Issues
  2. License: MIT
  3. README
  4. tokio-rs/mini-redis on GitHub
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/tokio-rs-mini-redis.svg)](https://hysenlabs.com/projects/tokio-rs-mini-redis)