StackExchange.Redis Connection String Format (and redis:// URIs)
/ 5 min read
Updated:Found this post helpful?
Buy me a coffeeTable of Contents
A StackExchange.Redis connection string is a comma-separated list of endpoints followed by key=value options. Here’s a typical one:
my-redis.example.com:6380,password=s3cr3t,ssl=true,abortConnect=falsePass it straight to ConnectionMultiplexer.Connect and you’re connected:
using StackExchange.Redis;
var redis = ConnectionMultiplexer.Connect( "my-redis.example.com:6380,password=s3cr3t,ssl=true,abortConnect=false");
var db = redis.GetDatabase();await db.StringSetAsync("hello", "world");The rest of this post covers the format, the options you’ll reach for most often, and what to do with the redis:// URIs many hosting providers give you, since StackExchange.Redis won’t parse those.
Install StackExchange.Redis from NuGet
If you haven’t already, add the StackExchange.Redis NuGet package to your project.
dotnet add package StackExchange.RedisThe Connection String Format
The official configuration docs describe the rules, and they boil down to three:
- Tokens are separated by commas.
- A token without an
=is a server endpoint, written ashostorhost:port. - A token with an
=is an option, such aspassword=s3cr3t.
If you leave off the port, StackExchange.Redis uses 6379, or 6380 when ssl=true.
Here are a few connection strings you’ll run into:
# Local Redis on the default portlocalhost
# Local Redis with a password and a non-default databaselocalhost:6379,password=s3cr3t,defaultDatabase=2
# Redis 6+ with an ACL userredis.example.com:6379,user=app,password=s3cr3t
# Azure Cache for Rediscontoso.redis.cache.windows.net:6380,password=<access-key>,ssl=true,abortConnect=false
# A primary/replica pair (the client figures out which is the primary)redis0:6379,redis1:6379,password=s3cr3tCommon Connection String Options
StackExchange.Redis supports a lot of options. These are the ones I find myself using most. Each option maps to a ConfigurationOptions property with the same name in PascalCase, except abortConnect, which maps to AbortOnConnectFail, and name, which maps to ClientName.
| Option | Default | What it does |
|---|---|---|
password={string} |
null |
Password for the Redis server |
user={string} |
null |
ACL username (Redis 6 and later) |
ssl={bool} |
false |
Use TLS. Most cloud providers require this |
abortConnect={bool} |
true (false on Azure) |
When true, Connect throws if no server is available |
defaultDatabase={int} |
null |
Database index used by GetDatabase() |
connectTimeout={int} |
5000 |
Timeout in milliseconds for connecting |
syncTimeout={int} |
5000 |
Timeout in milliseconds for synchronous operations |
asyncTimeout={int} |
same as syncTimeout |
Timeout in milliseconds for asynchronous operations |
connectRetry={int} |
3 |
Number of attempts during the initial connect |
name={string} |
null |
Name shown for this connection in CLIENT LIST |
allowAdmin={bool} |
false |
Enables risky commands like FLUSHDB and CONFIG |
Set abortConnect=false in production. With the default of true, your app fails to start if Redis is unreachable for a moment. With false, the multiplexer keeps retrying in the background and recovers when Redis comes back.
Building the Configuration in Code
You don’t have to keep everything in a string. ConfigurationOptions.Parse turns a connection string into an object you can tweak before connecting. This is useful when the basics live in configuration and some values are only known at runtime.
var options = ConfigurationOptions.Parse( builder.Configuration.GetConnectionString("Redis")!);
options.ClientName = "orders-api";options.AbortOnConnectFail = false;
var redis = ConnectionMultiplexer.Connect(options);It works the other way too. Calling options.ToString() gives you back the equivalent connection string, which helps when you’re debugging what a configuration turned into.
Register StackExchange.Redis in ASP.NET Core
ConnectionMultiplexer is expensive to create and designed to be shared, so register it as a singleton. IDatabase is a cheap pass-through object, so you can resolve it whenever you need it.
{ "ConnectionStrings": { "Redis": "localhost:6379,abortConnect=false" }}using StackExchange.Redis;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddSingleton<IConnectionMultiplexer>(_ => ConnectionMultiplexer.Connect( builder.Configuration.GetConnectionString("Redis")!));
builder.Services.AddScoped(sp => sp.GetRequiredService<IConnectionMultiplexer>().GetDatabase());
var app = builder.Build();
app.MapGet("/visits", async (IDatabase db) => await db.StringIncrementAsync("visits"));
app.Run();Converting a redis:// URI to a StackExchange.Redis Connection String
Many hosting providers, along with redis-cli -u, give you the connection details as a URI:
redis://username:password@host:port/databaserediss://username:password@host:port/databaseThe rediss:// scheme (with two s’s) means TLS. StackExchange.Redis doesn’t understand either scheme, so passing a URI straight to ConnectionMultiplexer.Connect won’t work. You have to convert it first.
System.Uri already knows how to pull a URI apart, so the conversion is short. The extension method below handles:
- both
redis://andrediss://, settingSslfor the latter - a username and password, a password only (
redis://:password@host), or no credentials at all - percent-encoded characters in the password, like
%40for@ - an optional database number in the path
- a missing port, which defaults to
6379
using StackExchange.Redis;
public static class RedisUri{ public static ConfigurationOptions Parse(string connectionUri) { var options = new ConfigurationOptions(); options.ApplyRedisUri(connectionUri); return options; }
public static ConfigurationOptions ApplyRedisUri( this ConfigurationOptions options, string connectionUri) { if (!Uri.TryCreate(connectionUri, UriKind.Absolute, out var uri) || uri.Scheme is not ("redis" or "rediss")) { throw new ArgumentException( "Expected a URI like redis://user:password@host:port/db " + "or rediss://... for TLS.", nameof(connectionUri)); }
var port = uri.Port > 0 ? uri.Port : 6379; options.EndPoints.Add(uri.Host, port); options.Ssl = uri.Scheme == "rediss";
if (!string.IsNullOrEmpty(uri.UserInfo)) { var parts = uri.UserInfo.Split(':', 2); if (parts.Length == 2) { var user = Uri.UnescapeDataString(parts[0]); if (user.Length > 0) options.User = user; options.Password = Uri.UnescapeDataString(parts[1]); } else { // redis://password@host is treated as a password-only URI options.Password = Uri.UnescapeDataString(parts[0]); } }
var path = uri.AbsolutePath.Trim('/'); if (int.TryParse(path, out var database)) { options.DefaultDatabase = database; }
return options; }}Here’s what a few URIs turn into. The right-hand side is the output of ToString() on the resulting ConfigurationOptions:
redis://localhost -> localhost:6379,ssl=False
redis://default:s3cr3t@redis.example.com:12345 -> redis.example.com:12345,user=default,password=s3cr3t,ssl=False
rediss://:p%40ss@redis.example.com:6380/2 -> redis.example.com:6380,password=p@ss,ssl=True,defaultDatabase=2Since ApplyRedisUri is an extension method on ConfigurationOptions, you can still set anything the URI can’t express before you connect:
var options = RedisUri.Parse(builder.Configuration["REDIS_URL"]!);options.AbortOnConnectFail = false;options.ClientName = "orders-api";
builder.Services.AddSingleton<IConnectionMultiplexer>( ConnectionMultiplexer.Connect(options));Hopefully, you find this extension method helpful the next time a provider hands you a redis:// URI. For every option I didn’t cover here, see the StackExchange.Redis configuration docs.