Skip to content

DOC-7165 Add a connection URLs page covering all client libraries - #4228

Merged
andy-stark-redis merged 1 commit into
mainfrom
DOC-7165
Oct 12, 2026
Merged

andy-stark-redis merged 1 commit into
mainfrom
DOC-7165

Conversation

@andy-stark-redis

@andy-stark-redis andy-stark-redis commented Oct 8, 2026 •

Copy link
Copy Markdown
Contributor

Adds a Connection URLs page to the client libraries section, covering the redis:///rediss:// URL format and how each client interprets it (DOC-7165, under epic DOC-7164).

Most clients accept a connection URL, but nothing in the docs explained the format. Only the node-redis pages showed it, as an inline format string. The URL format is only partly standardized. The redis and rediss schemes have a provisional IANA registration that defines the host, port, credentials, and database, and leaves query parameters to each client. The clients also differ on details inside that core.

Changes

  • New page develop/clients/connection-urls.md:
    • The URL format from the IANA registration.
    • Rules for writing URLs that behave the same in every client.
    • A summary table.
    • A short section for each client.
  • NOTE callouts linking to the client's section on the connect pages for redis-py, node-redis, ioredis, Jedis, Lettuce, go-redis, Predis, and StackExchange.Redis, and on the redis-rb and redis-rs index pages. The .NET note explains that StackExchange.Redis uses its own configuration string, and links to the conversion table.
  • The inline format string is removed from the two node-redis pages.

How the facts were checked

The client sections were checked against each client's URL-parsing source and tests at these releases:

  • redis-py 8.1.0
  • node-redis 6.3.0
  • ioredis 6.0.0
  • Jedis 8.0.2
  • Lettuce 7.8.0
  • go-redis 9.23.0
  • redis-rs 1.7.1
  • redis-rb 6.0.0 (its parser is in the redis-client gem, pinned to 0.30.1)
  • Predis 3.6.1
  • hiredis 1.4.1
  • StackExchange.Redis 3.3.1
  • NRedisStack 1.8.0

For most clients, parse-only runs (with no server) backed up the reading of the source. The clients' own docs weren't used as a source, because several disagree with their code. For example, the Jedis javadoc shows the port as optional, but Jedis rejects a URL without one.

Some findings that reviewers might not expect:

  • A value with no colon, as in redis://<value>@<host>: read as a username by most clients, as a password by Lettuce and redis-rb, and an error in Jedis. That's why the page recommends default:<password>@.
  • Unknown query parameters: go-redis returns an error, redis-py, ioredis, and Predis pass them to the client as options, and the other clients ignore them.
  • RESP version: redis-rs uses RESP2 unless the URL sets protocol. In ioredis, ?protocol=3 silently falls back to RESP2, so the page tells readers to set protocol in the options object instead.

For reviewers

  • The page isn't linked from the body of the clients section index. That matches the other cross-client pages, such as sch.md and pools-and-muxing.md, which readers reach through the sidebar and the client connect pages.
  • Client maintainers may want to check their own section. That's the most useful review for the per-client details.

🤖 Generated with Claude Code


Note

Low Risk
Documentation-only changes with no runtime or API impact; accuracy of client-specific URL behavior is the main review concern.

Overview
Adds a new Connection URLs guide under develop/clients that documents the redis:// / rediss:// shape (IANA provisional registration), rules for portable URLs across libraries, a comparison table, and per-client notes on entry points, query parameters, Unix sockets, TLS, cluster/Sentinel quirks, plus StackExchange.Redis configuration-string conversion and hiredis (no URL support).

Client docs are updated to point at that page: NOTE callouts on connect/index pages for redis-py, node-redis, ioredis, Jedis, Lettuce, go-redis, Predis, redis-rb, redis-rs, and .NET; go docs rename “connection string” to “connection URL”; node-redis drops the inline URL format string in favor of the dedicated page.

Reviewed by Cursor Bugbot for commit b43287a. Bugbot is set up for automated code reviews on this repo. Configure here.

Adds develop/clients/connection-urls.md. It covers the portable core of the
redis/rediss URL format, rules for writing URLs that behave the same across
clients, a summary table, and one section per client. Each client's connect
page (or index, for Ruby and Rust) gets a NOTE callout that links to its
section. The old inline format string on the node-redis pages is gone.

Every client-specific fact was checked against parser source and tests at
these releases: redis-py 8.1.0, node-redis 6.3.0, ioredis 6.0.0, Jedis 8.0.2,
Lettuce 7.8.0, go-redis 9.23.0, redis-rs 1.7.1, redis-rb 6.0.0 (whose URL
parsing lives in the redis-client gem, pinned to exactly 0.30.1), Predis 3.6.1,
hiredis 1.4.1, StackExchange.Redis 3.3.1 and NRedisStack 1.8.0. Where a
toolchain was available, parse-only runs backed this up. Nothing connected to
a server, so the page describes parse behavior, not handshakes.

The client projects' own docs were not reliable sources:
- Jedis javadoc shows the port as optional, but isValid() rejects a URI
  without one.
- Lettuce's URI guide uses Builder methods that no longer exist.
- The redis-rb docstring says the URL overrides explicit options. In fact
  the explicit options win.
- The node-redis clustering docs show a URL without a scheme, which parseURL
  rejects.
Read the parser source instead.

Some findings contradict common assumptions:
- redis://<value>@host without a colon is a username in most clients, a
  password in Lettuce and redis-rb, and an error in Jedis.
- go-redis rejects unknown query keys. redis-py, ioredis and Predis pass them
  through. The others ignore them.
- ioredis passes ?protocol=3 through as a string, so the RESP3 check fails and
  it silently uses RESP2. The page tells readers to set protocol in the
  options instead of describing the bug.

The IANA provisional registration (mirrored in redis/redis-specifications
uri/) is the closest thing to a spec. It explicitly says query parameters are
implementation-defined and not portable, which is why the page puts the
per-client sections after the portable core.

Learned: client URL docs (javadoc, READMEs, guides) contradict their own parsers in Jedis, Lettuce, redis-rb, node-redis; verify against parser source
Constraint: per-client facts on connection-urls.md are pinned to the releases listed in the body; re-verify a client's section against its parser source when bumping its version
Directive: keep query-parameter examples out of the portable-URL guidance; the spec defines no portable query keys
Gaps: StackExchange.Redis given a redis:// URL was read from code only (Parse treats it as a literal DnsEndPoint host); not executed
Gaps: handshake behavior (AUTH/SELECT/HELLO) after parsing was not exercised for any client
Recheck: ioredis protocol-as-string bug, if a fix lands the ioredis section can mention ?protocol=
Ticket: DOC-7165
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@github-actions

github-actions Bot commented Oct 8, 2026 •

Copy link
Copy Markdown
Contributor

DOC-7165

@github-actions

github-actions Bot commented Oct 8, 2026

Copy link
Copy Markdown
Contributor

🧠 Redis Memory

Found 5 related items from repository history (5 new this commit):

Memory updated at b43287a

andy-stark-redis added a commit that referenced this pull request Oct 12, 2026
Adds a "Connect to Redis Sentinel" section after the cluster section on
the nine connect.md pages (H3 on Jedis to match its neighbors). hiredis
gets a short "not supported" section: v1.4.1 has no Sentinel code.
Ruby and Rust had no connect pages; their Sentinel sections shipped
with the new pages in DOC-7168 (#4230, #4231).

Every snippet ran against a local topology (primary, replica, three
Sentinels, mymaster, quorum 2) in two variants: no auth, and separate
data-node and Sentinel passwords. Test copies differed from the page snippets
only in ports, passwords, and key names. Versions run: redis-py
8.1.0 (GitHub tag source), go-redis v9.23.0, node-redis 6.3.0, ioredis
6.0.0, Jedis 8.0.2, Lettuce 7.8.0, StackExchange.Redis 3.0.0 (NuGet was
blocked; latest is 3.3.1), Predis 3.6.1.

The failover caveats are measured, not inferred. Under a forced
SENTINEL FAILOVER, redis-py, ioredis (default options), a Lettuce
RedisClient connection, Predis, and SE.Redis 3.0.0 kept writing to the
demoted primary for about 10 s, until Sentinel reconfigured it, and the
old primary discarded those acknowledged writes on resync (22 of about
60 in the measured runs). go-redis, node-redis, and Jedis subscribe to
+switch-master and moved within 1-2 s; ioredis with failoverDetector
cut loss to the inherent sub-second window. The .NET page deliberately
has no caveat: 3.3.1 adds an IsStalePrimaryView path that may close the
window, and 3.3.1 couldn't be run here (needs the .NET 10 SDK).

Surprises worth knowing before editing these sections: Jedis
RedisSentinelClient has no replica reads at all; Predis replica routing
is sticky until the first write and the parameters username leaks to
the Sentinels (hence username in each Sentinel URI); go-redis
ReplicaOnly sends writes to the replica too; redis-py sentinel_kwargs
stops socket_* inheritance.

Learned: five of the eight clients on these pages silently lose ~10 s of writes after a graceful Sentinel failover
Constraint: every snippet here is run-verified (some trimmed to fragments of the tested program); re-run any edit against a real Sentinel topology
Rejected: SE.Redis SentinelUser/SentinelPassword options | 3.1.13+, source-read only, never run; page uses SentinelConnect + GetSentinelMasterConnection, which ran on 3.0.0
Rejected: Jedis .serverDefaultProtocol() to silence the 8.x RESP3 WARN | method doesn't exist in 7.x
Directive: add the SE.Redis failover caveat only after testing 3.3.1 or later under a forced failover
Directive: link the go-redis and Lettuce Sentinel URL forms to connection-urls.md once DOC-7165 (#4228) merges
Gaps: no TLS to Sentinels tested on any client; no crash failover, only graceful SENTINEL FAILOVER; SE.Redis 3.3.1 never run
Recheck: SE.Redis credentials example when the .NET 10 SDK is available to run 3.3.1
Ticket: DOC-7167
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@andy-stark-redis
andy-stark-redis merged commit 9fe4681 into main Oct 12, 2026
100 checks passed
@andy-stark-redis
andy-stark-redis deleted the DOC-7165 branch October 12, 2026 13:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

clients Client library docs

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants