{
  "schema_version": 2,
  "id": "develop/clients/rust/connect",
  "title": "Connect to the server",
  "url": "https://redis.io/docs/latest/develop/clients/rust/connect/",
  "summary": "Connect your Rust application to a Redis database",
  "tags": [
    "docs",
    "develop",
    "stack",
    "oss",
    "rs",
    "rc",
    "oss",
    "kubernetes",
    "clients"
  ],
  "last_updated": "2026-10-12T12:46:28+01:00",
  "page_type": "content",
  "content_hash": "91d1406608a530870ba56fa261b1d566169227b3177136d3fc34009ae506e9a7",
  "sections": [
    {
      "id": "basic-connection",
      "title": "Basic connection",
      "role": "overview",
      "text": "Synchronous connections need only `redis = \"1.7.1\"` in your `Cargo.toml` file. For\nasynchronous connections, also enable the `tokio-comp` feature and add\n[`tokio`](https://tokio.rs/):\n\n[code example]\n\nThe following example opens a synchronous connection, then stores and retrieves a\n[string](https://redis.io/docs/latest/develop/data-types/strings):\n\n[code example]\n\nThe asynchronous version uses `get_multiplexed_async_connection()`:\n\n[code example]\n\nTo connect as an [access control list (ACL)](https://redis.io/docs/latest/operate/oss_and_stack/management/security/acl)\nuser, add the username and password to the URL. The path selects the database number:\n\n[code example]\n\nYou can also build the connection details in code with `ConnectionInfo` and\n`RedisConnectionInfo`:\n\n[code example]\n\nTo connect through a Unix socket, use a `redis+unix://` URL. A Unix socket URL takes the\nusername, password, and database number as the `user`, `pass`, and `db` query parameters.\nThis differs from a `redis://` URL, which takes the credentials before the host and the\ndatabase number from the path.\n\n[code example]\n\nTo authenticate with Microsoft Entra ID, see\n[Connect to Azure Managed Redis](https://redis.io/docs/latest/develop/clients/rust/amr)."
    },
    {
      "id": "connect-to-a-redis-cluster",
      "title": "Connect to a Redis cluster",
      "role": "content",
      "text": "To connect to a Redis cluster, enable the `cluster` feature:\n\n[code example]\n\nThen pass one or more cluster nodes to `ClusterClient::new()`. The client discovers the\nrest of the cluster from these nodes:\n\n[code example]\n\nFor asynchronous connections, enable the `cluster-async` and `tokio-comp` features instead,\nand call `get_async_connection()`:\n\n[code example]\n\nBy default, the client sends every command to the primary node. To send read-only\ncommands to replicas, create the client with `ClusterClientBuilder` and set a read\nrouting strategy. `RandomReplicaStrategy` sends each read to a random replica of the\nkey's shard, and `RoundRobinReplicaStrategy` rotates through them. Writes still go to the\nprimary. Replication is asynchronous, so a replica can return stale data.\n\n[code example]"
    },
    {
      "id": "connect-to-redis-sentinel",
      "title": "Connect to Redis Sentinel",
      "role": "content",
      "text": "To connect through [Redis Sentinel](https://redis.io/docs/latest/operate/oss_and_stack/management/sentinel),\nenable the `sentinel` feature:\n\n[code example]\n\nThen create a client with `SentinelClientBuilder`. Pass one or more Sentinel addresses,\nthe name of the primary that the Sentinels monitor, and `SentinelServerType::Master`.\nEach call to `get_connection()` asks the Sentinels for the current primary and checks\nits role before it connects:\n\n[code example]\n\nThe Sentinels and the data nodes have separate credentials. Use the\n`set_client_to_sentinel_*` methods for the Sentinels, and the `set_client_to_redis_*`\nmethods for the primary and replicas:\n\n[code example]\n\nTo connect to a replica instead, pass `SentinelServerType::Replica`. The client connects\nto a replica chosen at random, and writes on that connection fail. Replication is\nasynchronous, so a replica can return stale data.\n\n[code example]\n\nA connection from `get_connection()` doesn't reconnect, and redis-rs doesn't listen for\nfailover announcements from the Sentinels. After a failover, the connection keeps using\nthe old primary until Sentinel reconfigures it as a replica and closes the connection.\nAny writes that the old primary accepts during that time are lost. When a command fails\nwith a connection error, call `get_connection()` again to connect to the new primary."
    },
    {
      "id": "connect-to-your-production-redis-with-tls",
      "title": "Connect to your production Redis with TLS",
      "role": "content",
      "text": "When you deploy your application, use Transport Layer Security (TLS) and follow the\n[Redis security](https://redis.io/docs/latest/operate/oss_and_stack/management/security) guidelines.\n\nCustom certificates need the rustls backend, so enable the `tls-rustls` feature, or\n`tokio-rustls-comp` for asynchronous connections. Also add the `rustls` crate, which\nprovides the cryptography:\n\n[code example]\n\nIf a certificate authority (CA) in your system's trust store signed the server's\ncertificate, a `rediss://` URL is all you need. To use Mozilla's root certificates\ninstead of the system trust store, enable the `tls-rustls-webpki-roots` feature.\n\n[code example]\n\nTo use your own CA certificate, or a client certificate and key for mutual TLS, pass the\nPrivacy-Enhanced Mail (PEM) files to `Client::build_with_tls()` in a `TlsCertificates`\nobject. rustls chooses a crypto provider automatically only when your dependencies enable\nexactly one, and the connection panics otherwise, so the following example installs one\nbefore it connects:\n\n[code example]"
    },
    {
      "id": "connect-using-client-side-caching",
      "title": "Connect using client-side caching",
      "role": "content",
      "text": "Client-side caching is a technique to reduce network traffic between\nthe client and server, resulting in better performance. See\n[Client-side caching introduction](https://redis.io/docs/latest/develop/clients/client-side-caching)\nfor more information about how client-side caching works and how to use it effectively.\n\n> [!NOTE]\n> Client-side caching is an\n> [experimental feature](https://docs.rs/redis/1.7.1/redis/caching/index.html) of\n> redis-rs. To maximize compatibility with all Redis products, client-side caching\n> is supported by Redis v7.4 or later.\n>\n> Client-side caching requires version 3 of the\n> [Redis serialization protocol (RESP3)](https://redis.io/docs/latest/develop/reference/protocol-spec#resp-versions),\n> and connecting with caching enabled over RESP2 fails with an error. It's\n> available only for asynchronous connections: `MultiplexedConnection`,\n> `ConnectionManager`, and the asynchronous `ClusterConnection`.\n\nEnable the `cache-aio` feature:\n\n[code example]\n\nThen pass a `CacheConfig` in an `AsyncConnectionConfig` when you connect.\n`CacheConfig::new()` enables caching with the default settings. Use\n`get_cache_statistics()` to check that the second `get()` call is served from the cache:\n\n[code example]"
    },
    {
      "id": "connection-management-and-pooling",
      "title": "Connection management and pooling",
      "role": "content",
      "text": "A `MultiplexedConnection` is cheap to clone, and all the clones share one underlying\nconnection, so you don't need a connection pool for asynchronous connections. Give each task\nits own clone:\n\n[code example]"
    },
    {
      "id": "reconnect-automatically",
      "title": "Reconnect automatically",
      "role": "content",
      "text": "A `MultiplexedConnection` doesn't reconnect after the connection drops. To reconnect\nautomatically, enable the `connection-manager` feature:\n\n[code example]\n\nThen use a `ConnectionManager`, which you can clone in the same way. The command that\nencounters the disconnection still fails, and the manager reconnects in the background\nfor the next command, so retry where that matters. To change the retry and timeout\nsettings, pass a `ConnectionManagerConfig` to `get_connection_manager_with_config()`.\n\n[code example]"
    },
    {
      "id": "pool-synchronous-connections",
      "title": "Pool synchronous connections",
      "role": "content",
      "text": "For synchronous connections, use an [r2d2](https://docs.rs/r2d2) pool to handle\ndisconnections and share connections between threads. Enable the `r2d2` feature and add\nthe `r2d2` crate:\n\n[code example]\n\nThe pool opens `max_size` connections when you build it. The default is 10.\n\n[code example]"
    },
    {
      "id": "timeouts",
      "title": "Timeouts",
      "role": "content",
      "text": "Asynchronous connections time out after 1 second when they connect, and after 500\nmilliseconds when they wait for a response. To change these timeouts, pass an\n`AsyncConnectionConfig` when you connect. Pass `None` to disable a timeout.\n`ConnectionManagerConfig` has the same defaults and setters.\n\n[code example]\n\nThe response timeout also applies to blocking commands. With the default timeout, a\n[`BLPOP`](https://redis.io/docs/latest/commands/blpop) that waits longer than 500 milliseconds fails with a\ntimeout error. Other commands on the same connection also time out until the server\nfinishes the blocking command, because the server doesn't process them in the meantime.\nSend blocking commands on a separate connection, with a response timeout longer than the\ncommand's own timeout, or none:\n\n[code example]\n\nSynchronous connections have no timeouts by default. `get_connection_with_timeout()`\nlimits the time to connect, and `set_read_timeout()` and `set_write_timeout()` limit each\nread and write on the connection:\n\n[code example]"
    },
    {
      "id": "protocol",
      "title": "Protocol",
      "role": "content",
      "text": "redis-rs uses the [RESP2](https://redis.io/docs/latest/develop/reference/protocol-spec#resp-versions)\nprotocol by default. To use RESP3, add `protocol=resp3` to the URL:\n\n[code example]\n\nYou can also set the protocol with `RedisConnectionInfo`:\n\n[code example]\n\nFor cluster and Sentinel clients, use `ClusterClientBuilder::use_protocol()` and\n`SentinelClientBuilder::set_client_to_redis_protocol()`."
    }
  ],
  "examples": [
    {
      "id": "basic-connection-ex0",
      "language": "toml",
      "code": "[dependencies]\nredis = { version = \"1.7.1\", features = [\"tokio-comp\"] }\ntokio = { version = \"1\", features = [\"full\"] }",
      "section_id": "basic-connection"
    },
    {
      "id": "basic-connection-ex1",
      "language": "rust",
      "code": "use redis::Commands;\n\nfn main() -> redis::RedisResult<()> {\n    let client = redis::Client::open(\"redis://localhost:6379/\")?;\n    let mut con = client.get_connection()?;\n\n    let _: () = con.set(\"foo\", \"bar\")?;\n    let val: String = con.get(\"foo\")?;\n    println!(\"foo: {val}\"); // foo: bar\n    Ok(())\n}",
      "section_id": "basic-connection"
    },
    {
      "id": "basic-connection-ex2",
      "language": "rust",
      "code": "use redis::AsyncCommands;\n\n#[tokio::main]\nasync fn main() -> redis::RedisResult<()> {\n    let client = redis::Client::open(\"redis://localhost:6379/\")?;\n    let mut con = client.get_multiplexed_async_connection().await?;\n\n    let _: () = con.set(\"foo\", \"bar\").await?;\n    let val: String = con.get(\"foo\").await?;\n    println!(\"foo: {val}\"); // foo: bar\n    Ok(())\n}",
      "section_id": "basic-connection"
    },
    {
      "id": "basic-connection-ex3",
      "language": "rust",
      "code": "let client = redis::Client::open(\"redis://<username>:<password>@localhost:6379/0\")?;",
      "section_id": "basic-connection"
    },
    {
      "id": "basic-connection-ex4",
      "language": "rust",
      "code": "use redis::{ConnectionAddr, IntoConnectionInfo, RedisConnectionInfo};\n\nlet info = ConnectionAddr::Tcp(\"localhost\".to_string(), 6379)\n    .into_connection_info()?\n    .set_redis_settings(\n        RedisConnectionInfo::default()\n            .set_username(\"default\") // use your Redis user\n            .set_password(\"secret\") // use your Redis password\n            .set_db(0),\n    );\nlet client = redis::Client::open(info)?;",
      "section_id": "basic-connection"
    },
    {
      "id": "basic-connection-ex5",
      "language": "rust",
      "code": "let client = redis::Client::open(\"redis+unix:///tmp/redis.sock?user=<username>&pass=<password>&db=0\")?;",
      "section_id": "basic-connection"
    },
    {
      "id": "connect-to-a-redis-cluster-ex0",
      "language": "toml",
      "code": "[dependencies]\nredis = { version = \"1.7.1\", features = [\"cluster\"] }",
      "section_id": "connect-to-a-redis-cluster"
    },
    {
      "id": "connect-to-a-redis-cluster-ex1",
      "language": "rust",
      "code": "use redis::cluster::ClusterClient;\nuse redis::Commands;\n\nfn main() -> redis::RedisResult<()> {\n    let nodes = vec![\n        \"redis://localhost:16379/\",\n        \"redis://localhost:16380/\",\n        \"redis://localhost:16381/\",\n    ];\n    let client = ClusterClient::new(nodes)?;\n    let mut con = client.get_connection()?;\n\n    let _: () = con.set(\"foo\", \"bar\")?;\n    let val: String = con.get(\"foo\")?;\n    println!(\"foo: {val}\"); // foo: bar\n    Ok(())\n}",
      "section_id": "connect-to-a-redis-cluster"
    },
    {
      "id": "connect-to-a-redis-cluster-ex2",
      "language": "rust",
      "code": "let mut con = client.get_async_connection().await?;",
      "section_id": "connect-to-a-redis-cluster"
    },
    {
      "id": "connect-to-a-redis-cluster-ex3",
      "language": "rust",
      "code": "use redis::cluster::ClusterClientBuilder;\nuse redis::cluster_read_routing::RandomReplicaStrategy;\n\nlet client = ClusterClientBuilder::new(nodes)\n    .read_routing_strategy(RandomReplicaStrategy)\n    .build()?;\nlet mut con = client.get_connection()?;\n\nlet val: String = con.get(\"foo\")?; // Read from a replica",
      "section_id": "connect-to-a-redis-cluster"
    },
    {
      "id": "connect-to-redis-sentinel-ex0",
      "language": "toml",
      "code": "[dependencies]\nredis = { version = \"1.7.1\", features = [\"sentinel\"] }",
      "section_id": "connect-to-redis-sentinel"
    },
    {
      "id": "connect-to-redis-sentinel-ex1",
      "language": "rust",
      "code": "use redis::sentinel::{SentinelClientBuilder, SentinelServerType};\nuse redis::{Commands, ConnectionAddr};\n\nfn main() -> redis::RedisResult<()> {\n    let sentinels = vec![\n        ConnectionAddr::Tcp(\"localhost\".to_string(), 26379),\n        ConnectionAddr::Tcp(\"localhost\".to_string(), 26380),\n        ConnectionAddr::Tcp(\"localhost\".to_string(), 26381),\n    ];\n    let mut client =\n        SentinelClientBuilder::new(sentinels, \"mymaster\", SentinelServerType::Master)?.build()?;\n    let mut con = client.get_connection()?;\n\n    let _: () = con.set(\"foo\", \"bar\")?;\n    let val: String = con.get(\"foo\")?;\n    println!(\"foo: {val}\"); // foo: bar\n    Ok(())\n}",
      "section_id": "connect-to-redis-sentinel"
    },
    {
      "id": "connect-to-redis-sentinel-ex2",
      "language": "rust",
      "code": "let mut client = SentinelClientBuilder::new(sentinels, \"mymaster\", SentinelServerType::Master)?\n    .set_client_to_sentinel_password(\"sentinel-secret\") // use your Sentinel password\n    .set_client_to_redis_username(\"default\") // use your Redis user\n    .set_client_to_redis_password(\"secret\") // use your Redis password\n    .build()?;",
      "section_id": "connect-to-redis-sentinel"
    },
    {
      "id": "connect-to-redis-sentinel-ex3",
      "language": "rust",
      "code": "let mut replica =\n    SentinelClientBuilder::new(sentinels, \"mymaster\", SentinelServerType::Replica)?.build()?;\nlet mut con = replica.get_connection()?;\n\nlet val: String = con.get(\"foo\")?;",
      "section_id": "connect-to-redis-sentinel"
    },
    {
      "id": "connect-to-your-production-redis-with-tls-ex0",
      "language": "toml",
      "code": "[dependencies]\nredis = { version = \"1.7.1\", features = [\"tls-rustls\"] }\nrustls = \"0.23\"",
      "section_id": "connect-to-your-production-redis-with-tls"
    },
    {
      "id": "connect-to-your-production-redis-with-tls-ex1",
      "language": "rust",
      "code": "let client = redis::Client::open(\"rediss://<username>:<password>@my-redis.example.com:6379\")?;",
      "section_id": "connect-to-your-production-redis-with-tls"
    },
    {
      "id": "connect-to-your-production-redis-with-tls-ex2",
      "language": "rust",
      "code": "use redis::{ClientTlsConfig, Commands, TlsCertificates};\nuse std::fs;\n\nfn main() -> redis::RedisResult<()> {\n    // Install a crypto provider for rustls before you connect.\n    rustls::crypto::aws_lc_rs::default_provider()\n        .install_default()\n        .expect(\"Failed to install the rustls crypto provider\");\n\n    let client = redis::Client::build_with_tls(\n        \"rediss://<username>:<password>@my-redis.example.com:6379\",\n        TlsCertificates {\n            client_tls: Some(ClientTlsConfig {\n                client_cert: fs::read(\"redis_user.crt\")?,\n                client_key: fs::read(\"redis_user_private.key\")?,\n            }),\n            root_cert: Some(fs::read(\"redis_ca.pem\")?),\n        },\n    )?;\n    let mut con = client.get_connection()?;\n\n    let _: () = con.set(\"foo\", \"bar\")?;\n    let val: String = con.get(\"foo\")?;\n    println!(\"foo: {val}\"); // foo: bar\n    Ok(())\n}",
      "section_id": "connect-to-your-production-redis-with-tls"
    },
    {
      "id": "connect-using-client-side-caching-ex0",
      "language": "toml",
      "code": "[dependencies]\nredis = { version = \"1.7.1\", features = [\"tokio-comp\", \"cache-aio\"] }\ntokio = { version = \"1\", features = [\"full\"] }",
      "section_id": "connect-using-client-side-caching"
    },
    {
      "id": "connect-using-client-side-caching-ex1",
      "language": "rust",
      "code": "use redis::caching::CacheConfig;\nuse redis::{AsyncCommands, AsyncConnectionConfig};\n\n#[tokio::main]\nasync fn main() -> redis::RedisResult<()> {\n    let client = redis::Client::open(\"redis://localhost:6379/?protocol=resp3\")?;\n    let config = AsyncConnectionConfig::new().set_cache_config(CacheConfig::new());\n    let mut con = client.get_multiplexed_async_connection_with_config(&config).await?;\n\n    let _: () = con.set(\"city\", \"New York\").await?;\n    let _: String = con.get(\"city\").await?; // Retrieved from the server and cached\n    let _: String = con.get(\"city\").await?; // Retrieved from the cache\n\n    let stats = con.get_cache_statistics().unwrap();\n    println!(\"hits: {}, misses: {}\", stats.hit, stats.miss); // hits: 1, misses: 1\n    Ok(())\n}",
      "section_id": "connect-using-client-side-caching"
    },
    {
      "id": "connection-management-and-pooling-ex0",
      "language": "rust",
      "code": "let con = client.get_multiplexed_async_connection().await?;\n\nlet tasks: Vec<_> = (1..=3)\n    .map(|i| {\n        let mut con = con.clone(); // Shares the same underlying connection\n        tokio::spawn(async move { con.incr::<_, _, i64>(\"counter\", i).await })\n    })\n    .collect();\nfor task in tasks {\n    task.await.unwrap()?;\n}",
      "section_id": "connection-management-and-pooling"
    },
    {
      "id": "reconnect-automatically-ex0",
      "language": "toml",
      "code": "[dependencies]\nredis = { version = \"1.7.1\", features = [\"tokio-comp\", \"connection-manager\"] }\ntokio = { version = \"1\", features = [\"full\"] }",
      "section_id": "reconnect-automatically"
    },
    {
      "id": "reconnect-automatically-ex1",
      "language": "rust",
      "code": "let client = redis::Client::open(\"redis://localhost:6379/\")?;\nlet mut con = client.get_connection_manager().await?;\n\nlet _: () = con.set(\"foo\", \"bar\").await?;",
      "section_id": "reconnect-automatically"
    },
    {
      "id": "pool-synchronous-connections-ex0",
      "language": "toml",
      "code": "[dependencies]\nredis = { version = \"1.7.1\", features = [\"r2d2\"] }\nr2d2 = \"0.8\"",
      "section_id": "pool-synchronous-connections"
    },
    {
      "id": "pool-synchronous-connections-ex1",
      "language": "rust",
      "code": "use redis::Commands;\n\nlet client = redis::Client::open(\"redis://localhost:6379/\")?;\nlet pool = r2d2::Pool::builder().max_size(15).build(client).unwrap();\n\nlet mut con = pool.get().unwrap();\nlet _: () = con.set(\"foo\", \"bar\")?;",
      "section_id": "pool-synchronous-connections"
    },
    {
      "id": "timeouts-ex0",
      "language": "rust",
      "code": "use redis::AsyncConnectionConfig;\nuse std::time::Duration;\n\nlet config = AsyncConnectionConfig::new()\n    .set_connection_timeout(Some(Duration::from_secs(5)))\n    .set_response_timeout(Some(Duration::from_secs(2)));\nlet mut con = client.get_multiplexed_async_connection_with_config(&config).await?;",
      "section_id": "timeouts"
    },
    {
      "id": "timeouts-ex1",
      "language": "rust",
      "code": "let config = AsyncConnectionConfig::new().set_response_timeout(None);\nlet mut con = client.get_multiplexed_async_connection_with_config(&config).await?;\n\n// Waits up to 5 seconds for an item.\nlet item: Option<(String, String)> = con.blpop(\"queue\", 5.0).await?;",
      "section_id": "timeouts"
    },
    {
      "id": "timeouts-ex2",
      "language": "rust",
      "code": "use std::time::Duration;\n\nlet con = client.get_connection_with_timeout(Duration::from_secs(5))?;\ncon.set_read_timeout(Some(Duration::from_secs(2)))?;\ncon.set_write_timeout(Some(Duration::from_secs(2)))?;",
      "section_id": "timeouts"
    },
    {
      "id": "protocol-ex0",
      "language": "rust",
      "code": "let client = redis::Client::open(\"redis://localhost:6379/?protocol=resp3\")?;",
      "section_id": "protocol"
    },
    {
      "id": "protocol-ex1",
      "language": "rust",
      "code": "use redis::{ConnectionAddr, IntoConnectionInfo, ProtocolVersion, RedisConnectionInfo};\n\nlet info = ConnectionAddr::Tcp(\"localhost\".to_string(), 6379)\n    .into_connection_info()?\n    .set_redis_settings(RedisConnectionInfo::default().set_protocol(ProtocolVersion::RESP3));\nlet client = redis::Client::open(info)?;",
      "section_id": "protocol"
    }
  ]
}
