InletDownload

Redis connection string

Redis connection string: redis:// and rediss:// URLs explained

A Redis URL is redis://[[user][:password]@]host[:port][/db-number]: port 6379 and database 0 unless you say otherwise, and rediss:// for TLS. With a password and no user, keep the colon (redis://:password@host). Options after ? mean different things to different clients.

Updated 9 October 2026

The format

redis[s]://[[user][:password]@]host[:port][/db-number][?options]
PartExampleNotes
Schemeredis:// or rediss://rediss:// means TLS.
UserappAn ACL user (Redis 6 and later). Empty, or default, for the built-in default user.
Password:<password>That user’s password, or the server’s requirepass password. Percent-encode special characters.
Hostcache.example.comlocalhost if left out.
Port:63796379 if left out. Hosted services often use another.
Database/15A number, 0 if left out. A default server has databases 0 to 15.
Options?protocol=3Defined by each client library, not by Redis.

Both schemes are provisional registrations with IANA, made in 2015. They describe connecting, then sending AUTH if there’s a password and SELECT if there’s a database number. The rediss registration notes that the name follows HTTPS, “and is not a typo”. Redis had no user names then, so it advised leaving the user part blank; since ACLs arrived in Redis 6, clients send it as the user to sign in as.

Tested with redis-cli 8.10.2 against Redis 8.10.2:

redis-cli -u 'redis://inlet:<password>@localhost:6379/15' PING
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
PONG

redis-cli prints that warning whenever the password is on the command line, because other users of the machine can see it. Put it in the REDISCLI_AUTH environment variable instead, or add --no-auth-warning if you accept the risk.

User and password

redis://:<password>@cache.example.com:6379          # password only: the default user
redis://default:<password>@cache.example.com:6379   # the same, with the user named
redis://app:<password>@cache.example.com:6379       # an ACL user

With redis://:<password>@…, ACL WHOAMI answered default. An ACL user gets only what its rules allow. Our reader user can read but not write:

redis://reader:…@localhost:6379/15   GET seo:connect:url   → ok
redis://reader:…@localhost:6379/15   SET seo:connect:url … → NOPERM User reader has no permissions to run the 'set' command

Always write the colon. Clients disagree about a single word before the @:

  • redis-cli and Lettuce read it as the password. redis-cli -u 'redis://inlet@localhost:6379/15' signed in as default (whose password on our test server happens to be inlet), and redis://reader@… failed with WRONGPASS invalid username-password pair or user is disabled.
  • redis-py, ioredis and node-redis read it as the user name, with no password.
  • Jedis refuses it: Password not provided in uri.

redis://:<password>@host and redis://<user>:<password>@host mean the same to all of them. redis-cli’s own help suggests default as the user when you have no user name.

Special characters in the password

Percent-encode anything that has a meaning in a URL: @ : / ? # % and spaces, among others. We gave a temporary Redis 8.10.2 server the password p@ss:w/rd#1:

redis://:p%40ss%3Aw%2Frd%231@localhost:6379/0   → PONG
redis://:p@ss:w/rd#1@localhost:6379/0           → Could not connect to Redis at ss:0: Name or service not known

Unencoded, the first @ ended the password, so redis-cli took ss as the host. redis-py, node-redis, ioredis and Jedis all decode percent-encoded user names and passwords too. More in special characters in passwords.

The database number

The path is the database number. On a server with the default 16 databases, a key set through …:6379/15 wasn’t there through …:6379/0 (EXISTS returned 0).

  • Out of range, redis-cli warns and carries on in database 0, with a success exit code:

    SELECT 16 failed: ERR DB index is out of range
    
  • Some clients also take it as an option: redis-py’s ?db= and Lettuce’s ?database= win over the path. redis-cli ignores the query string: with /15?db=3, it was in database 15.

  • Cluster mode has only database 0. On a Redis 8.10.2 cluster node, SELECT 1 returned ERR SELECT is not allowed in cluster mode. Redis Cloud and Upstash also offer database 0 only.

TLS: rediss://

rediss:// turns TLS on and, in most clients, checks the server’s certificate against the system’s trusted roots. Against our TLS-only Redis 8.10.2 server, whose certificate comes from a private CA:

redis-cli -u 'rediss://inlet:…@localhost:6390/15' PING                     → SSL_connect failed: certificate verify failed
redis-cli -u 'rediss://inlet:…@localhost:6390/15' --cacert ca.pem PING     → PONG
redis-cli -u 'redis://inlet:…@localhost:6390/15' PING                      → Error: Connection reset by peer

The full failure reads Could not connect to Redis at localhost:6390: SSL_connect failed: certificate verify failed. --insecure skips the check (for a throwaway test only). In our test redis-cli checked the certificate chain but not the host name: a certificate for localhost was accepted under another name.

Hosted services that require TLS (Upstash always, Redis Cloud once you turn it on, ElastiCache with in-transit encryption) need rediss://. With redis:// the connection fails: the server drops it, or, on ElastiCache, it hangs.

Options after the ?

The IANA registration leaves query options to each client, and they really do differ:

ClientHow you pass a URLOptions it reads from the query string
redis-cliredis-cli -u '<url>'None. Use flags: -3 for RESP3, --cacert, --insecure. With ?protocol=3 our session stayed on RESP2.
redis-pyredis.from_url('<url>')db, protocol (?protocol=3 for RESP3), socket_timeout, socket_connect_timeout, health_check_interval, ssl_cert_reqs (none, optional, required), ssl_check_hostname and more. Query options win over keyword arguments.
node-rediscreateClient({ url: '<url>' })None: it reads the user, password, host, port and database only. Set RESP: 3 and socket: { tls: … } in the options object.
ioredisnew Redis('<url>')Any: each one becomes an option of the same name (as a string; family as a number).
Jedisnew JedisPooled(URI.create('<url>'))protocol (?protocol=3).
LettuceRedisURI.create('<url>')timeout, clientName, libraryName, libraryVersion, database.

From each client’s current documentation or source, October 2026. A URL written for one client can carry options another ignores, or trips over. Turning off certificate checks (?ssl_cert_reqs=none in redis-py) is for testing only.

Unix sockets

A server listens on a socket only if unixsocket is set in its config (it’s commented out in the stock redis.conf). Then:

  • redis-cli -s /path/to/redis.sock. Its -u takes only redis:// and rediss://; with unix:// it prints Invalid URI scheme.
  • redis-py: unix:///path/to/redis.sock?db=0, with &password=<password> if needed.
  • node-redis: unix://[[user][:password]@]/path/to/redis.sock[?db=N].
  • ioredis: the path itself, new Redis('/path/to/redis.sock').
  • Lettuce: redis-socket:///path/to/redis.sock.

Examples

# Local, no password
redis://localhost:6379

# Local, requirepass, database 2
redis://:<password>@localhost:6379/2

# ACL user over TLS on a hosted service
rediss://app:<password>@cache.example.com:12345/0

# Upstash (the token is the password)
rediss://default:<token>@<endpoint>:6379

Valkey accepts the same URLs, and valkey-cli also takes valkey://; see Connect to Valkey.

In Inlet

Paste a redis:// or rediss:// URL into a new connection and Inlet fills in the form: host, port, the ACL user or password only, the database number, and TLS for rediss://, with the server’s certificate checked. Client certificates and SSH tunnels are set in the same form. The password goes in the Keychain, or Inlet asks for it every time. For provider specifics, see Redis in Docker or Homebrew, Upstash, Redis Cloud and Amazon ElastiCache.

Related

Sources