# redis-oxide
[](https://crates.io/crates/redis-oxide)
[](https://docs.rs/redis-oxide)
[](https://github.com/nghiaphamln/redis-oxide#license)
`redis-oxide` is an async Redis client for Rust. It provides topology detection,
Redis Cluster support, Sentinel support, connection pooling, RESP2/RESP3
protocol handling, Pub/Sub, Streams, Lua scripting, transactions, and pipelines.
The crate is designed for Tokio applications that need a practical Redis client
with a typed API and predictable behavior across standalone and clustered Redis
deployments.
## Installation
```toml
[dependencies]
redis-oxide = "0.2.3"
tokio = { version = "1", features = ["full"] }
```
## Quick Start
```rust
use redis_oxide::{Client, ConnectionConfig};
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let config = ConnectionConfig::new("redis://localhost:6379");
let client = Client::connect(config).await?;
client.set("greeting", "hello").await?;
if let Some(value) = client.get("greeting").await? {
println!("{value}");
}
Ok(())
}
```
## Core Operations
```rust
use std::collections::HashMap;
use std::time::Duration;
// Assume `client` is a connected redis_oxide::Client.
client.set("key", "value").await?;
client.set_ex("session", "active", Duration::from_secs(60)).await?;
let value: Option<String> = client.get("key").await?;
let ttl: Option<i64> = client.ttl("session").await?;
client.hset("user:1", "name", "Nghia").await?;
let fields: HashMap<String, String> = client.hgetall("user:1").await?;
client.lpush("jobs", vec!["job-1".to_string(), "job-2".to_string()]).await?;
let jobs: Vec<String> = client.lrange("jobs", 0, -1).await?;
client.sadd("tags", vec!["rust".to_string(), "redis".to_string()]).await?;
let tags = client.smembers("tags").await?;
let mut scores = HashMap::new();
scores.insert("alice".to_string(), 10.0);
scores.insert("bob".to_string(), 12.0);
client.zadd("leaderboard", scores).await?;
```
`ttl` preserves Redis sentinel values. A missing key returns `Some(-2)` and a key
without expiration returns `Some(-1)`.
## Advanced Usage
### Pipelines
```rust
let mut pipeline = client.pipeline();
pipeline.set("key:1", "value:1");
pipeline.set("key:2", "value:2");
pipeline.get("key:1");
let results = pipeline.execute().await?;
```
Redis server errors inside a pipeline are returned as per-command
`RespValue::Error` entries. Transport and connection failures still fail the
whole pipeline.
### Transactions
```rust
let mut transaction = client.transaction().await?;
transaction.watch(vec!["balance".to_string()]).await?;
transaction.get("balance");
transaction.set("balance", "120");
let results = transaction.exec().await?;
```
### Lua Scripts
```rust
use redis_oxide::Script;
let script = Script::new(
"return KEYS[1] .. ':' .. ARGV[1]"
);
let result: String = script.execute(
&client,
vec!["user".to_string()],
vec!["42".to_string()],
).await?;
```
`Script::execute` tries `EVALSHA` first and falls back to `EVAL` when Redis
returns `NOSCRIPT`.
### Pub/Sub
```rust
client.publish("events", "created").await?;
let mut subscriber = client.subscriber().await?;
subscriber.subscribe(vec!["events".to_string()]).await?;
if let Some(message) = subscriber.next_message().await? {
println!("{}: {}", message.channel, message.payload);
}
```
### Streams
```rust
use std::collections::HashMap;
let mut fields = HashMap::new();
fields.insert("event".to_string(), "created".to_string());
let id = client.xadd("events", "*", fields).await?;
let messages = client
.xread(vec![("events".to_string(), "0".to_string())], Some(10), None)
.await?;
```
## Configuration
```rust
use redis_oxide::{ConnectionConfig, PoolConfig, PoolStrategy, ProtocolVersion};
use std::time::Duration;
let config = ConnectionConfig::new("redis://localhost:6379")
.with_operation_timeout(Duration::from_secs(10))
.with_protocol_version(ProtocolVersion::Resp2)
.with_pool_config(PoolConfig {
strategy: PoolStrategy::Multiplexed,
max_size: 10,
min_idle: 2,
connection_timeout: Duration::from_secs(5),
});
```
Use `ConnectionConfig::new("redis://host1:6379,host2:6379")` with cluster
topology detection enabled for Redis Cluster deployments. Sentinel configuration
is available through `SentinelConfig`.
## Development
Required toolchain:
- Rust 1.82.0 or newer
- Redis available on `localhost:6379` for integration tests
Quality gates:
```bash
cargo fmt --all --check
cargo check --workspace --all-targets
cargo clippy --workspace --all-targets -- -D warnings
cargo test --workspace --all-targets
cargo doc --workspace --no-deps --document-private-items
cargo audit
cargo deny check
```
## Documentation
- [Getting started](docs/getting-started.md)
- [Architecture](docs/architecture.md)
- [Performance](docs/performance.md)
- [Troubleshooting](docs/troubleshooting.md)
- [Changelog](CHANGELOG.md)
- [Contributing](CONTRIBUTING.md)
- [API documentation](https://docs.rs/redis-oxide)
## Compatibility
- Rust: 1.82.0 or newer
- Redis: 6.0 or newer
- Platforms: Linux, macOS, Windows
- Runtime: Tokio
## License
This project is licensed under the MIT License. See [LICENSE-MIT](LICENSE-MIT).