Skip to content

[ruby] Update redis 5.4.1 → 6.0.0 (major) - #849

Merged
digitaltom merged 1 commit into
mainfrom
depfu/update/redis-6.0.0
Aug 7, 2026
Merged

[ruby] Update redis 5.4.1 → 6.0.0 (major)#849
digitaltom merged 1 commit into
mainfrom
depfu/update/redis-6.0.0

Conversation

@depfu

@depfu depfu Bot commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

Here is everything you need to know about this update. Please take a good look at what changed and the test results before merging this pull request.

What changed?

✳️ redis (5.4.1 → 6.0.0) · Repo · Changelog

Release Notes

6.0.0

This is a major release of the redis and redis-clustering gems. The headline change is that the client now speaks RESP3 by default, alongside first-class support for the Redis Query Engine and the JSON module, a batch of new Redis 6.2–8.10 commands, and experimental support for the Redis 8.10 HIMPORT bulk-ingestion command family.

Command return values are unchanged from 5.x with one exception (GEO coordinates, see below), so for most applications this upgrade is a Gemfile bump.

Requires Ruby 3.2+ and works with Redis server 6.0+ (older servers are handled via automatic RESP2 fallback).

RESP3 by default

RESP3's richer wire types (native maps, doubles, booleans) let the parser deliver replies already in their final Ruby shape. Under RESP2, structured replies arrive as flat arrays of bulk strings that the client must re-shape in Ruby — e.g. HGETALL builds a Hash from a flat [field, value, ...] array, and sorted-set scores are converted StringFloat pair by pair. Under RESP3 that re-shaping pass disappears.

Measured with bench/resp_comparison.rb (redis-rb 6.0.0, Ruby 3.4.1, Redis 8.8, localhost, 100-element replies):

Pure-Ruby driver (default):

Workload RESP2 → RESP3 RPS (8 threads) RESP2 → RESP3 µs CPU/op
GET (50B string) 4251 → 4436 (+4%) 23.4 → 22.9 (~0)
HGETALL (100 fields) 2361 → 2560 (+8%) 164 → 129 (−22%)
ZRANGE WITHSCORES (100) 2597 → 2459 (−5%) 130 → 147 (~0, noise)
XRANGE (100 entries) 1544 → 1570 (+2%) 346 → 328 (~0)

hiredis driver (C parser):

Workload RESP2 → RESP3 RPS (8 threads) RESP2 → RESP3 µs CPU/op
GET 12756 → 12620 (~0) 69 → 70 (~0)
HGETALL 10175 → 10592 (+4%) 97 → 89 (−8%; 1 thread: 88 → 63, −28%)
ZRANGE WITHSCORES 10036 → 11629 (+16%) 108 → 85 (−22%)
XRANGE 7053 → 6999 (~0) 152 → 152 (~0)

In short: hash reads use ~10–25% less client CPU per call on both drivers; sorted-set reads with scores gain up to 16% throughput and ~20% less CPU with hiredis (unchanged on the pure-Ruby driver, where parsing RESP3 doubles costs roughly what the re-shaping pass did); simple string and stream commands are unaffected — their reply shapes are the same in both protocols. RESP3 pairs best with the hiredis driver, which moves all reply construction out of Ruby and into C.

Methodology note: figures are per-reply CPU measurements against a localhost server; wall-clock throughput gains in production depend on how network-bound your workload is.

Beyond performance, RESP3 also lays the groundwork for push-based features — such as server-assisted client-side caching (CLIENT TRACKING invalidation events) — in future 6.x releases, without another protocol migration.

🔥 Breaking changes

  • RESP3 by default (see above); pass protocol: 2 to keep RESP2. The only return-value change is GEO coordinates as Float. (#1351)
  • Requires Ruby 3.2+ (previously 2.7/2.6). Bundler will keep older Rubies on the 5.4.x series automatically. (#1353, #1365)

Cluster gem (redis-clustering) only

  • Commands are now routed by their server-declared command tips (redis-cluster-client 0.16.6+): SLOWLOG GET returns one entry list per master; SLOWLOG LEN and LATENCY RESET return the sum across all masters; FUNCTION LOAD/DELETE/FLUSH/RESTORE now execute on all masters (previously a single arbitrary node — this also fixes FCALL failing for keys on other masters); commands with keys in subcommands (e.g. XINFO STREAM) route to the key's slot owner.

🚀 New features

  • Redis Query Engine (RediSearch, FT.*): ft_create, ft_alter, ft_dropindex, ft_info, ft_search, ft_aggregate, vector and hybrid search, suggestions, dictionaries, synonyms, aliases, and spellcheck. Not supported by Redis::Distributed. (#1356, #1359, #1360, #1361)
  • JSON module: json_set, json_get, json_mset, json_mget, json_del, json_forget, json_clear, json_merge, json_arr*, json_obj*, json_str*, json_numincrby, json_toggle, json_type, json_debug_memory. (#1346, #1347, #1348, #1349)
  • lmovem and blmovem — multi-element list moves (Redis 8.10). (#1363)
  • sunioncard and sdiffcard (Redis 8.10). (#1357)
  • xread / xreadgroup now accept max_count: and max_size: (Redis 8.10). (#1358)
  • Hash field TTLs: hexpire, hpexpire, httl, hpttl (Redis 7.4). (#1324, #1325, #1331)
  • hscan / hscan_each now accept novalues: true (Redis 7.4). (#1327)
  • geosearch and geosearchstore (Redis 6.2); geo commands are now available on Redis::Distributed. (#1342)
  • geoadd now accepts nx:, xx:, ch:; geo radius searches accept count_any:; xadd accepts limit: (Redis 6.2). (#1345)
  • Redis::Distributed now implements hscan, hscan_each and hstrlen. (#1319)
  • Identify the client to the server via CLIENT SETINFO (lib-name=redis-rb, lib-ver=<version>). Extend the reported name with driver_info:, or disable with driver_info: false. See the README "Client identification" section. (#1369)

⚠️ Experimental

  • HIMPORT command family (Redis 8.10, hinted hash templates): himport_prepare, himport_set, himport_discard, himport_discard_all, available on standalone clients, pipelines/transactions, Redis::Distributed, and the cluster client. Lost fieldsets (reconnect, failover, RESET) are re-prepared and retried automatically; disable with himport_auto_prepare: false. In cluster mode, prepare/discard fan out to all masters and himport_set routes by its key's hash slot. The API may change in a future minor release. See the README "Bulk hash ingestion (HIMPORT)" section. (#1364)

🐛 Bug fixes

  • Fix FloatifyPairs to not re-transform already transformed replies. (#1354)
  • unlink now returns 0 for an empty keyset, consistent with del. (#1316)

🧰 Maintenance

  • redis-rb is now maintained by Redis Ltd.
  • Pin redis-client to the exact version 0.30.1 (previously >= 0.22.0); includes the reply-desynchronization fix from 0.26.4. The cluster gem pins redis-cluster-client to0.16.7. Driver upgrades are now deliberate, suite-verified releases. (#1350, #1352)
  • Test suite now runs against prebuilt redislabs/client-libs-test Docker images; CI covers MRI 3.2/3.3/3.4/4.0 and TruffleRuby against Redis 7.2–8.10. (#1317, #1318, #1344)
  • Drop the unused executables config from the gemspec. (#1322)

Upgrade notes

  1. Requires Ruby 3.2+. Applications on older Rubies will keep resolving to redis 5.4.x.
  2. If you post-process GEO coordinates as strings, adapt to Float values — or pass protocol: 2 and migrate at your own pace.
  3. Cluster users relying on single-node behavior of SLOWLOG/LATENCY/FUNCTION commands should review the routing changes above.
  4. Everything else is drop-in.

Does any of this look wrong? Please let us know.

Commits

See the full diff on Github. The new version differs by more commits than we can show here.

↗️ redis-client (indirect, 0.25.1 → 0.30.1) · Repo · Changelog

Release Notes

0.30.1 (from changelog)

  • hiredis-client: Use pkg-config to locate OpenSSL. Should fix compilation issue on precompiled rubies such as the ones from mise.

0.30.0 (from changelog)

  • hiredis-client: Now support configuring SSL verify_mode.

0.29.0 (from changelog)

  • Fix connecting to Redis 7.1 and older with driver_info:set.
  • Added RedisClient::Error#next_error for an easier way to check all errors produced by a pipeline.

0.28.0 (from changelog)

  • Added RedisClient::HashRing for horizontal sharing (compatible with Redis::Distributed from redis-rb).

0.27.0 (from changelog)

  • Added idle_timeout to revalidate connections that haven't been successfuly used in a long time. Defaults to 60 seconds.
  • Added driver_info configuration, to issue CLIENT SETINFO during connection prelude.

0.26.4 (from changelog)

  • Further improve rediss:// URLs used with Redis sentinel. Now avoid override explictly set ssl: paramter.
  • Fix compatibility with redis-rb in sentinel mode.

0.26.3 (from changelog)

  • Fix rediss:// (ssl) URLs used with Redis sentinel.
  • Handle Ruby 4.0 connection timeout raising an IO::Timeout instead of Errno::ETIMEDOUT.
  • Entirely close the connection on authentication failures.

0.26.2 (from changelog)

  • Fix compatibility with connection_pool version 3+.

0.26.1 (from changelog)

  • Fix a few corner cases where RedisClient::Error#final? was innacurate.
  • hiredis-client: Properly reconnect to the new leader after a sentinel failover.

0.26.0 (from changelog)

  • Add RedisClient::Error#final? and #retriable? to allow middleware to filter out non-final errors.

  • Fix precedence of db: nil initialization parameter.

    Redis.new(url: "redis://localhost:6379/3", db: nil).db

    Before: 0 After: 3

0.25.3 (from changelog)

  • Fix hiredis-client compilation with clang 21.

0.25.2 (from changelog)

  • Fix circuit breakers to respect the error_threshold_timeout config is provided.
  • Fix circuit breakers to clear errors when closing back.

Does any of this look wrong? Please let us know.

Commits

See the full diff on Github. The new version differs by more commits than we can show here.


Depfu Status

Depfu will automatically keep this PR conflict-free, as long as you don't add any commits to this branch yourself. You can also trigger a rebase manually by commenting with @depfu rebase.

All Depfu comment commands
@​depfu rebase
Rebases against your default branch and redoes this update
@​depfu recreate
Recreates this PR, overwriting any edits that you've made to it
@​depfu merge
Merges this PR once your tests are passing and conflicts are resolved
@​depfu cancel merge
Cancels automatic merging of this PR
@​depfu close
Closes this PR and deletes the branch
@​depfu reopen
Restores the branch and reopens this PR (if it's closed)
@​depfu pause
Ignores all future updates for this dependency and closes this PR
@​depfu pause [minor|major]
Ignores all future minor/major updates for this dependency and closes this PR
@​depfu resume
Future versions of this dependency will create PRs again (leaves this PR as is)

@depfu depfu Bot added the depfu label Aug 7, 2026
@digitaltom
digitaltom merged commit 7ef1f44 into main Aug 7, 2026
6 checks passed
@depfu
depfu Bot deleted the depfu/update/redis-6.0.0 branch August 7, 2026 08:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant