Update module github.com/go-redis/redis/v7 to v9 - #59
Open
renovate[bot] wants to merge 1 commit into
Open
Conversation
Contributor
Author
⚠ Artifact update problemRenovate failed to update an artifact related to this branch. You probably do not want to merge this PR as-is. ♻ Renovate will retry this branch, including artifacts, only when one of the following happens:
The artifact failure details are included below: File name: go.sum |
renovate
Bot
force-pushed
the
renovate/github.com-go-redis-redis-v7-9.x
branch
from
April 3, 2023 11:09
78baed4 to
1ce16fd
Compare
renovate
Bot
force-pushed
the
renovate/github.com-go-redis-redis-v7-9.x
branch
2 times, most recently
from
May 29, 2023 07:39
9d352af to
f81b488
Compare
renovate
Bot
force-pushed
the
renovate/github.com-go-redis-redis-v7-9.x
branch
from
August 17, 2023 13:36
f81b488 to
5ec58a1
Compare
renovate
Bot
force-pushed
the
renovate/github.com-go-redis-redis-v7-9.x
branch
2 times, most recently
from
September 27, 2023 11:08
c33fec8 to
1176b7d
Compare
renovate
Bot
force-pushed
the
renovate/github.com-go-redis-redis-v7-9.x
branch
from
October 23, 2023 13:04
1176b7d to
61aa3a5
Compare
renovate
Bot
force-pushed
the
renovate/github.com-go-redis-redis-v7-9.x
branch
from
October 31, 2023 16:59
61aa3a5 to
e36825f
Compare
renovate
Bot
force-pushed
the
renovate/github.com-go-redis-redis-v7-9.x
branch
from
December 19, 2023 12:59
e36825f to
56ab320
Compare
renovate
Bot
force-pushed
the
renovate/github.com-go-redis-redis-v7-9.x
branch
from
January 7, 2024 13:33
56ab320 to
3873d3f
Compare
renovate
Bot
force-pushed
the
renovate/github.com-go-redis-redis-v7-9.x
branch
2 times, most recently
from
February 20, 2024 21:33
e8a16bb to
3fa0be8
Compare
renovate
Bot
force-pushed
the
renovate/github.com-go-redis-redis-v7-9.x
branch
from
May 31, 2024 04:12
3fa0be8 to
4d11529
Compare
Contributor
Author
|
renovate
Bot
force-pushed
the
renovate/github.com-go-redis-redis-v7-9.x
branch
from
June 7, 2024 15:01
4d11529 to
5367382
Compare
renovate
Bot
force-pushed
the
renovate/github.com-go-redis-redis-v7-9.x
branch
2 times, most recently
from
July 15, 2024 18:48
35e2429 to
5d295cf
Compare
renovate
Bot
force-pushed
the
renovate/github.com-go-redis-redis-v7-9.x
branch
2 times, most recently
from
July 25, 2024 11:25
bd7d969 to
06351a4
Compare
renovate
Bot
force-pushed
the
renovate/github.com-go-redis-redis-v7-9.x
branch
2 times, most recently
from
October 17, 2024 13:13
e5c5d28 to
e49a454
Compare
renovate
Bot
force-pushed
the
renovate/github.com-go-redis-redis-v7-9.x
branch
from
June 6, 2025 22:37
474eb01 to
4be4383
Compare
renovate
Bot
force-pushed
the
renovate/github.com-go-redis-redis-v7-9.x
branch
from
June 13, 2025 03:45
35a3f4c to
4be4383
Compare
renovate
Bot
force-pushed
the
renovate/github.com-go-redis-redis-v7-9.x
branch
from
June 24, 2025 15:00
4be4383 to
62c6da5
Compare
renovate
Bot
force-pushed
the
renovate/github.com-go-redis-redis-v7-9.x
branch
from
July 12, 2025 23:00
240ff12 to
62c6da5
Compare
renovate
Bot
force-pushed
the
renovate/github.com-go-redis-redis-v7-9.x
branch
2 times, most recently
from
August 11, 2025 17:24
16e78ee to
8129115
Compare
renovate
Bot
force-pushed
the
renovate/github.com-go-redis-redis-v7-9.x
branch
2 times, most recently
from
September 10, 2025 13:42
1521258 to
f3b165d
Compare
renovate
Bot
force-pushed
the
renovate/github.com-go-redis-redis-v7-9.x
branch
from
September 19, 2025 08:38
53f2953 to
f3b165d
Compare
renovate
Bot
force-pushed
the
renovate/github.com-go-redis-redis-v7-9.x
branch
from
October 19, 2025 02:56
f3b165d to
6659bf7
Compare
renovate
Bot
force-pushed
the
renovate/github.com-go-redis-redis-v7-9.x
branch
3 times, most recently
from
October 23, 2025 17:04
f1973db to
8eaad1a
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This PR contains the following updates:
v7.4.1→v9.22.0Release Notes
go-redis/redis (github.com/go-redis/redis/v7)
v9.22.0: 9.22.0Compare Source
This is a minor release introducing two flagship (experimental) features — client-side caching and automatic pipelining — alongside support for Redis 8.10, new commands, and a large batch of stability and parser-robustness fixes. It consolidates everything shipped in 9.22.0-beta.1, so the notes below cover the full 9.21.0 → 9.22.0 upgrade.
WaitAOFreturn type corrected (#3888):WaitAOFnow returns*IntSliceCmd, matching the two-integer reply ofWAITAOF(previously*IntCmd, which failed to parse the reply at runtime). Code referencing the old return type needs a one-line update.🚀 Highlights
Client-Side Caching (Experimental)
The standalone
Clientgains server-assisted client-side caching built on RESP3CLIENT TRACKING. Enable it by settingClientSideCacheConfiginOptions(or supply your own cache viaClientSideCache— e.g. to share one cache across clients). Cacheable read results are served from a local in-process cache and invalidated automatically when the server reports a change, cutting round trips for read-heavy workloads.The invalidation architecture is selected by
ClientSideCacheStrategy; the default (and currently only) strategy isCSCStrategySharedTracking: one shared cache, every pool connection runs plainCLIENT TRACKING ON, and a background drainer applies buffered invalidations — portable (no BCAST) and consistent with the other Redis client libraries. Requirements and guardrails: RESP3 (Protocol: 3), standalone client, DB 0 only; commands that would change the connection identity (SELECT,AUTH, ...) are rejected while caching is enabled, and CSC is disabled when a credentials provider is set (fixedUsername/Passwordwork and are namespaced). See the README's client-side caching section and the runnable example.Experimental: the API may change in a minor release.
(#3941) by @ofekshenawa
Automatic Pipelining (Experimental)
AutoPipelineris a background batcher that coalesces commands from many concurrent goroutines into Redis pipelines, multiplying throughput without any manual pipeline management. It comes in two faces, available onClientandClusterClient(and configurable viaOptions.AutoPipelineOptions/UniversalOptions.AutoPipelineOptions):AutoPipeline()— the blocking face: a drop-inCmdablewhere each call blocks until executed, exactly like a plain client, while concurrent callers' commands batch together under the hood (measured locally over loopback: ~1M+ SET/sec vs ~100k unpipelined; indicative, not a guarantee). Per-goroutine command order is preserved.AsyncAutoPipeline()— the deferred face: command calls return immediately and every typed result accessor (Val/Result/Err/...) blocks until the command has executed. Submit a window of commands, then read the results, to keep pipelines deep (~2–3M SET/sec locally; indicative).AutoPipelineOptionscontrols batching:MaxBatchSize(soft target, default 200; the blocking face's preset uses 300),MaxBatchBytes(approximate payload cap so huge values flush as several bounded writes),MaxFlushDelaywith optionalAdaptiveDelay(delay scales down as the queue fills), andMaxConcurrentBatches(default 1 = a single ordered batch stream; raising it requiresUnordered: true, so ordering is never lost by accident —Validate()rejects the combination otherwise). A usage tour and throughput comparison live inexample/autopipeline.Experimental: the API may change in a future release — pin your go-redis version if you adopt it.
(#3942) by @ndyakov, with help from @cxljs
Redis 8.10 Support
This release adds support for Redis 8.10. The README's supported-versions list now includes Redis 8.10, and CI runs the full suite against the
redislabs/client-libs-test:8.10.0image by default (#3920, #3940).Coverage for the new commands and options that ship with Redis 8.10:
HIMPORT(#3919) — bulk hash import via server-side fieldsets, exposed asHImportPrepare,HImportSet,HImportDiscard, andHImportDiscardAll. Fieldsets are session state scoped to a single physical connection, which does not mix well with connection pooling — so the client keeps a versioned fieldset registry and lazily replays thePREPAREon whichever pooled connection executes aSETthat needs it, at most once per connection, with no extra round trip (thePREPAREis injected into the same write as theSET).LMOVEM/BLMOVEM(#3913) — move multiple elements between lists in one call.SUNIONCARD/SDIFFCARD(#3897) — cardinality of set union/difference without materializing the result.XREAD/XREADGROUPMAXCOUNTandMAXSIZE(#3898) — bound how much data a stream read returns.TS.READ(#3896),TS.QUERYLABELS(#3926),TS.NRANGE/TS.NREVRANGE(#3870) with multiple aggregators per key (#3937), andEXCLUDEEMPTYonTS.MRANGE/TS.MREVRANGE(#3912) — new time-series query surface.FT.ALIASLIST(#3925),COLLECTreducer forFT.AGGREGATE(#3886),RERANKon HNSW vector fields inFT.CREATE(#3927), andFT.HYBRIDtimeout warnings (#3911) — search coverage.Cross-SDK Aligned Defaults
Default configuration values now follow the cross-SDK configuration proposal shared by all Redis client libraries (#3918):
ReadTimeout/WriteTimeoutnet.KeepAliveConfig)Applications that set these values explicitly are unaffected; applications relying on the old defaults inherit the new ones.
Data-Race and Parser Hardening Sweep
A systematic audit fixed data races across the client — hooks (
AddHook, #3868),Ring.SetAddrs(#3862), cluster node slices (#3861), pub/sub reconnect (#3906), maintenance notifications (#3894, #3872), pool handoff (#3876), andredisotel(#3881) — and hardened the RESP parsers against malformed or unexpected replies: over-reads on nil replies (#3874), integer overflow when skipping map/attribute bodies (#3877), unhashable RESP3 map keys (#3873), odd-length flat replies (#3900), mismatched declared array lengths (#3907), unexpected extra reply frames (#3884), and nil elements in numeric/bool slice replies (#3922).PubSub
ReceiveHang FixPeekPushNotificationNameblocked until 36 bytes were buffered, so a short subscribe confirmation (channel name of six or fewer characters) on an otherwise idle connection hungPubSub.Receiveforever — a regression introduced in 9.20.1 by #3842. The peek now parses whatever is already buffered and only waits for one more byte when the frame prefix is valid but incomplete. Fixes #3935.(#3936) by @ndyakov
Correct Cluster Transaction Retries
The cluster transaction pipeline treated a
MULTI...EXECblock as independently retryable commands, which could scatter a transaction across nodes or send malformed transactions on retry. Redirects (MOVED/ASK/TRYAGAIN) and aborts are now handled at the whole-transaction level, matching Redis transaction semantics: the transaction is re-routed and retried as a unit, never partially (#3909) by @cxljs.Credential Redaction in Command Tracing
rediscmd.AppendCmd— used byredisotelandrediscensusto render commands into span attributes — now redacts credential arguments as<redacted>:AUTH,HELLO ... AUTH,CONFIG SETofrequirepass/masterauth/ TLS key passphrases,ACL SETUSERpassword rules, andMIGRATE ... AUTH/AUTH2. The client sendsHELLO ... AUTHon every handshake andAUTHon every streaming-credentials rotation through the regular hook chain, so tracing hooks previously captured credentials even when the application never issued an auth command itself (#3939) by @saddamr3e.✨ New Features
ClientSideCacheConfig/ClientSideCache, with theCSCStrategySharedTrackinginvalidation strategy (#3941) by @ofekshenawaAutoPipeline()(blocking) andAsyncAutoPipeline()(deferred results) onClientandClusterClient, configured viaAutoPipelineOptions(#3942) by @ndyakov, with help from @cxljsHIMPORTcommand family:HImportPrepare/HImportSet/HImportDiscard/HImportDiscardAllwith lazy per-connection fieldset prepare replay (#3919) by @ndyakovLMOVEM/BLMOVEM: move multiple list elements in one call, withCOUNT(up to N) orEXACTLY(all-or-nothing) semantics viaLMoveMArgs(#3913) by @ofekshenawaSUnionCard/SDiffCard: cardinality of set union/difference (#3897) by @ofekshenawaXRead/XReadGroupMAXCOUNT/MAXSIZE: bound stream read responses by entry count or payload size (#3898) by @ofekshenawaTS.READ: read samples from a series starting at a given timestamp, withTSReadEarliest(-),TSReadLatest(+), andTSReadNew($) sentinels (#3896) by @ofekshenawaTS.QUERYLABELS: query label names/values across time series (#3926) by @ndyakovTS.NRANGE/TS.NREVRANGE: range queries across multiple series (#3870) by @ofekshenawa, with multiple aggregators per key (#3937) by @ndyakovTS.MRANGE/TS.MREVRANGEEXCLUDEEMPTY: skip series with no samples in the result (#3912) by @ofekshenawaFT.ALIASLIST: list all index aliases (#3925) by @ndyakovFT.AGGREGATECOLLECTreducer: collect grouped values into an array (#3886) by @ndyakovFT.CREATERERANK:RERANKparameter on HNSW vector field definitions (#3927) by @ofekshenawaFT.HYBRIDtimeout warnings: timeout warnings are now populated in hybrid search results (#3911) by @ofekshenawaFT.HYBRIDKNNSHARD_K_RATIO(Redis 8.8+): per-shard K ratio for KNN clauses (#3841) by @ndyakov🐛 Bug Fixes
Receivehang: peek push-notification names without demanding 36 buffered bytes, fixing a hang on short subscribe confirmations (fixes #3935, regression from 9.20.1) (#3936) by @ndyakovrediscmd.AppendCmdredacts credential arguments (AUTH,HELLO ... AUTH,CONFIG SETsecret params,ACL SETUSERpassword rules,MIGRATE AUTH/AUTH2), soredisotel/rediscensusspan attributes no longer contain passwords (#3939) by @saddamr3eWaitAOFreturn type: returns*IntSliceCmdmatching the two-integerWAITAOFreply (#3888) by @CipherN9Ring.Publishrouting: publish to the shard that owns the topic instead of a round-robined one (#3893) by @dkindelOnRemovehooks: fireOnRemoveonputConneviction paths so removal hooks see every evicted connection (#3932) by @cxljsUniversalClientInfoMap: addedInfoMapto theCmdableinterface (#3904) by @nazarli-shabnamSlowLogGetcontext: pass the caller's context instead of a background one (#3915) by @sonnemuskModuleLoadexnil config: return an error instead of panicking on nil config (#3916) by @sonnemuskParseURLIPv6 hosts: keep single brackets for IPv6 hosts without a port (#3882) by @sueun-devParseURLdurations: treat unit durations<= 0as disabled (#3866) by @sueun-dev*uint8encoding: encode nil*uint8as"0"like other numeric pointers (#3869) by @sueun-devJSONSliceCmdread errors: return the read error fromreadReplyinstead of swallowing it (#3903) by @saddamr3eReader.Discard(#3874) by @saddamr3e; reject unhashable keys in RESP3 map parsing (#3873) by @iabdullah215AddHook(#3868),onNewNodeduringRing.SetAddrs(#3862), shared masters/slaves slices in cluster (#3861), sharedopt.Addrduring pub/sub reconnect (#3906),clusterStateReloadCallbackin maintnotifications (#3894), conn reader inisHealthyConnduring handoff (#3876) by @saddamr3e; handoff race window in maintnotifications (#3872) by @ndyakovredisotel: useObservableCounterfor cumulative pool stats (#3914) by @Solaris-star; avoid a data race on shared attributes duringMinIdleConnswarmup (#3881) by @ndyakov🧰 Maintenance
redislabs/client-libs-test:8.10.0image and 8.8 was dropped from the CI matrix (#3940)sync/atomicvalue types (#3860) and remove the deadassertUnstableCommandRESP3 path (#3928) by @cxljsExpireTime/PExpireTimereturn Unix timestamps (#3917) by @sonnemusk; remove a duplicate example step (#3875) by @andy-stark-redis👥 Contributors
We'd like to thank all the contributors who worked on this release!
@andy-stark-redis, @CipherN9, @cxljs, @dkindel, @iabdullah215, @nazarli-shabnam, @ndyakov, @ofekshenawa, @saddamr3e, @Solaris-star, @sonnemusk, @sueun-dev
Full Changelog: redis/go-redis@v9.21.0...v9.22.0
v9.21.0: 9.21.0Compare Source
This is a minor release adding new features and bug fixes. There are no breaking changes; upgrading from 9.20.x is a drop-in replacement.
🚀 Highlights
Zero-copy
GetToBuffer/SetFromBufferTwo new
StringCmdablemethods let callers read and write Redis string values directly into and from pre-allocated byte buffers, eliminating the per-call payload allocation thatGet/Setincur:GetToBufferdecodes the bulk reply straight into the caller-ownedbuf(no intermediate allocation); a buffer that is too small returns an error after draining the payload, so the connection stays aligned for the next reply.SetFromBufferis provided for API symmetry — it dispatches to the same[]bytewriter path asSet(ctx, key, buf, 0)and produces byte-identical output on the wire. Available on*Client,*ClusterClient,*Ring,*ConnandPipeliner.(#3834) by @ndyakov
Explicit
LIMIT 0for stream trimmingRedis treats
XTRIM/XADDapproximate-trim (~)LIMIT 0as "disable the trimming effort cap entirely", which differs from omittingLIMIT(the implicit100 * stream-node-max-entriesdefault). The command builders previously only emittedLIMITwhenlimit > 0, so callers could never send an explicitLIMIT 0. Following theKeepTTL = -1precedent, the newXTrimLimitDisabled = -1sentinel now emits an explicitLIMIT 0;limit == 0keeps the historical no-LIMITbehavior, so existing callers produce byte-identical commands.(#3848) by @TheRealMal
✨ New Features
GetToBuffer/SetFromBufferonStringCmdableand theZeroCopyStringCmdresult type, reading/writing string values into caller-owned buffers without per-call payload allocation (#3834) by @ndyakovXTrimLimitDisabledsentinel:XTRIM/XADDapproximate trimming can now send an explicitLIMIT 0to disable the trim effort cap, via the newXTrimLimitDisabled = -1sentinel (#3848) by @TheRealMalchannel.initHealthChecknow bounds thePingit issues with a fresh per-check timeout context (the exportedpingTimeout/reconnectTimeout) instead ofcontext.TODO(), so a stuck health-check Ping can no longer block indefinitely (#3819) by @abdellaniUNWATCHinTx.Close: a transaction now tracks whether aWATCHis still active (watchArmed) and only issuesUNWATCHonClosewhen it is, removing an extra round trip on the commonWATCH/.../EXECand no-keyWatchpaths while never returning a connection to the pool with an active watch (#3854) by @fcostaoliveira🐛 Bug Fixes
maintnotificationsModeAutofail-open:ModeAutonow stays fail-open when the server does not support maintenance notifications — connections are retired and tracking is guarded during downgrade so the client keeps working instead of erroring (#3853) by @terrorobe👥 Contributors
We'd like to thank all the contributors who worked on this release!
@abdellani, @fcostaoliveira, @ndyakov, @terrorobe, @TheRealMal
v9.20.1: 9.20.1Compare Source
This is a patch release containing bug fixes only. There are no new features or breaking changes; upgrading from 9.20.0 is a drop-in replacement.
🚀 Highlights
RESP3 pub/sub message loss fixed
PeekPushNotificationNamepreviously inspected only the bytes already buffered bybufio, so when a push frame header straddled a buffer fill boundary it could return a truncated notification name (e.g."messa"instead of"message"). The push processor then mis-routed the frame andReadReplysilently dropped it, causing intermittent RESP3 pub/sub message loss. The peek now grows its window (36 bytes → up to 4 KiB) and reads more from the connection until the header is complete, cleanly separating incomplete prefixes from corrupt frames (including overflow-safe bulk-length handling). Fixes #3839.(#3842) by @ndyakov
🐛 Bug Fixes
PeekPushNotificationNameno longer returns a truncated notification name when a push frame header spans a buffer boundary, preventing silent RESP3 pub/sub message loss (fixes #3839) (#3842) by @ndyakovFT.HYBRIDvector params: Vector data is now always sent viaPARAMSwith auto-generated param names (__vector_param_N, with collision avoidance) whenVectorParamNameis omitted, since Redis no longer accepts inline vector blobs; theFTHybridOptions.Paramsmap is no longer mutated, so the same options struct can be reused across calls (#3844) by @ndyakovCLUSTER SHARDSforward compatibility: Unknown shard- and node-level attributes in theCLUSTER SHARDSreply are now skipped viaDiscardNext()instead of erroring, so clients keep working when the server introduces new fields (#3843) by @madolsonPubSub.releaseConnno longer reconnects twice when a connection is both unusable (or pending handoff) and reports a bad-connection error, avoiding a wasted connection establish-then-close cycle (#3833) by @cxljs👥 Contributors
We'd like to thank all the contributors who worked on this release!
@cxljs, @madolson, @ndyakov
Full Changelog: redis/go-redis@v9.20.0...v9.20.1
v9.20.0: 9.20.0Compare Source
🚀 Highlights
Redis 8.8 Support
This release adds support for Redis 8.8. The README's supported-versions list now includes Redis 8.8 alongside 8.0/8.2/8.4, and CI exercises the
8.8client-libs-test image across the full suite (Makefile, build workflow, doctests, run-tests action, and docker-compose).Coverage for the new commands that ship in the 8.x line, rounded out in this release:
AR*array data type (#3813) — new array data structure, exposed via theArrayCmdableinterface (see the experimental-features highlight below).INCREX(#3816) — atomic increment with expiration in a single round-trip.XNACK(#3790) — explicit negative-acknowledge of pending stream entries.XAUTOCLAIMPEL deletes (#3798) —XAUTOCLAIM/XAUTOCLAIMJUSTIDnow return the list of deleted message IDs from the pending entries list.TS.RANGEmultiple aggregators (#3791) —TS.RANGE/TS.REVRANGE/TS.MRANGE/TS.MREVRANGEaccept multiple aggregators in a single call.Z(UNION|INTER|DIFF)COUNTaggregator (#3802) —COUNTreducer for sorted-set set operations.JSON.SET FPHA(#3797) — newFPHAargument that specifies the floating-point type for homogeneous FP arrays.CI image bump (#3814) by @ofekshenawa. Command coverage contributions by @cxljs, @elena-kolevska, @Khukharr, @ndyakov, and @ofekshenawa.
Stable RESP3 for RediSearch (
UnstableResp3deprecated)FT.SEARCH,FT.AGGREGATE,FT.INFO,FT.SPELLCHECK, andFT.SYNDUMPnow parse RESP3 (map) responses into the same typed result objects as RESP2 —Val()andResult()work uniformly on both protocols, no flag required. Previously, RESP3 search responses requiredUnstableResp3: trueand were returned as opaque maps accessible only viaRawResult()/RawVal().As a result, the
UnstableResp3option is now a no-op across every options struct (Options,ClusterOptions,UniversalOptions,FailoverOptions,RingOptions) and has been marked// Deprecated:. The field is retained for backwards compatibility — existing code that setsUnstableResp3: truewill continue to compile and behave identically — but it will be removed in a future release and new code should not set it.RawResult()/RawVal()continue to work for callers that prefer the raw RESP payload.(#3741) by @ndyakov
Experimental Array Data Structure Commands
Adds an experimental
ArrayCmdableinterface with theAR*command family (ARSet,ARGet,ARGetRange,ARMSet,ARMGet,ARDel,ARDelRange,ARScan,ARSeek,ARNext,ARLastItems,ARGrep,ARGrepWithValues,ARInfo/ARInfoFull, and typed reducersAROpSum/AROpMin/AROpMax/AROpAnd/AROpOr/AROpXor/AROpMatch/AROpUsed) for working with Redis 8.8's new array data type. API is experimental and may change in a future release.(#3813) by @cxljs
✨ New Features
FT.SEARCH/FT.AGGREGATE/FT.INFO/FT.SPELLCHECK/FT.SYNDUMPresponses with backwards compatibility for RESP2 (#3741) by @ndyakovINCREXcommand support — atomic increment with expiration (#3816) by @ndyakovXNACKstream command for explicitly negative-acknowledging pending entries (#3790) by @elena-kolevskaTS.RANGE/TS.REVRANGE/TS.MRANGE/TS.MREVRANGEnow accept multiple aggregators in a single call (#3791) by @elena-kolevskaXAutoClaimdeleted IDs:XAUTOCLAIM/XAUTOCLAIMJUSTIDnow return the list of deleted message IDs from the PEL (#3798) by @KhukharrJSON.SET FPHA:JSON.SETaccepts a newFPHAargument that specifies the floating-point type for homogeneous floating-point arrays (#3797) by @ndyakovZUNION/ZINTER/ZDIFFaggregator now supportsCOUNT(#3802) by @ofekshenawaFT.HYBRIDvector validation: Validates hybrid-search vector input types and adds proper typed vector parameters (#3756) by @DengY11ClusterClient.PoolStats()now accumulatesWaitCountandWaitDurationNsacross all node pools (previously always zero) (#3809) by @LINKIWI🐛 Bug Fixes
CLUSTER SLOTSport-0 entries now fall back to the origin endpoint's port, fixingdial tcp <ip>:0: connection refusedon TLS-only clusters started with--port 0 --tls-port <port>(fixes #3726) (#3828) by @ndyakovPubSub.conn()now passes both regular (c.channels) and sharded (c.schannels) channels into the per-PubSubnewConnclosure. Previously,ClusterClient.SSubscribe-only PubSubs reconnected to a random node (because the routing closure saw an empty channel list), theSSUBSCRIBEwas sent to the wrong shard, and the resultingMOVEDreply was silently dropped (#3829) by @ndyakovWatchretry: User errors returned from aWatchcallback are no longer subjected to cluster-retry classification; transient cluster errors still retry, but a callback returning e.g.net.ErrClosedshort-circuits immediately (#3821) by @obiyangMasterAddr's concurrent sentinel probe now closes the non-winning sentinel clients instead of leaking them (#3827) by @cxljsreplicaAddrsno longer tears down the cached sentinel client when the replica list is empty, eliminating a continuous rediscovery loop on master-only Sentinel deployments that flooded logs and added per-operation latency (#3795) by @shahyash2609CloseConnhooks:Pool.CloseConnnow triggers registered hooks, fixing a memory leak when connections are closed explicitly rather than via the normal removal path (#3818) by @ndyakovdial tcperrors are now correctly classified as redirectable so cluster routing can recover from a single unreachable node (#3810) by @vladisa88Closehealth checks:ConnPool.Closenow only runs health checks against idle connections, avoiding spurious activity on connections still in use (#3805) by @ndyakovVLINKS/VLINKSWITHSCORESvector-set replies (#3820) by @romanpovol🧪 Testing & Infrastructure
waitForSentinelClusterStablepost-conditions: The sentinel test harness now waits for replicas to be fully connected (not just present in the count) and is robust to randomized spec ordering after failover specs, eliminating an intermittentExpected master to equal slaveflake (#3830) by @ndyakovgovulncheckworkflow: New scheduled GitHub Actions workflow runsgovulncheckon every push, PR, and weekly, surfacing newly disclosed Go vulnerabilities even when no code changes (#3779) by @solardome🧰 Maintenance
Cmd.Slot()lookup refactor: Caches the per-commandCommandInfoand short-circuits keyless commands before the switch dispatch, removing redundantPeekcalls (#3804) by @retr0-kernelmath/rand: Replacedinternal/randwithmath/randfrom the standard library now that the minimum Go version is 1.24 (#3823) by @cxljsConnPool, trimming the pool's footprint (#3826) by @cxljsextra/*package (#3817) by @ndyakov👥 Contributors
We'd like to thank all the contributors who worked on this release!
@cxljs, @DengY11, @elena-kolevska, @Khukharr, @LINKIWI, @ndyakov, @obiyang, @ofekshenawa, @retr0-kernel, @romanpovol, @shahyash2609, @solardome, @vladisa88
Full Changelog: redis/go-redis@v9.19.0...v9.20.0
v9.19.0: 9.19.0Compare Source
🚀 Highlights
FIPS-Compatible Script Helper
Scriptnow supports a FIPS-safe execution mode that avoids client-side SHA-1 computation, which is blocked in strict FIPS environments. A newNewScriptServerSHAconstructor usesSCRIPT LOADto obtain and cache the digest from the server, then runs commands viaEVALSHA/EVALSHA_RO. Falls back toEVAL/EVALROif loading fails, and transparently retries once onNOSCRIPT. The default behavior is unchanged for existing users.(#3700) by @chaitanyabodlapati
FT.AGGREGATE Step-Based Pipeline Builder
Added a new step-based
FT.AGGREGATEpipeline API viaFTAggregateOptions.Steps, allowingLOAD,APPLY,GROUPBY, andSORTBY(with per-stepMAX) to be repeated and interleaved in arbitrary order — matching Redis's native multi-stage aggregation semantics. The legacyLoad/Apply/GroupBy/SortBy/SortByMaxfields are now deprecated.(#3782) by @ndyakov
Raw RESP Protocol Access
Added
DoRawandDoRawWriteTomethods for executing arbitrary commands and reading the raw RESP response. Useful for proxying, custom protocol inspection, and working with commands not yet wrapped by go-redis.(#3713) by @ofekshenawa
Configurable Dial Retry Backoff
Added
DialerRetryBackoffoption (plumbed throughOptions,ClusterOptions,RingOptions,FailoverOptions) to let callers customize the delay between failed dial attempts. HelpersDialRetryBackoffConstantandDialRetryBackoffExponential(with jitter and cap) are provided out of the box. Dial timeout is now also applied per attempt rather than across all retries.(#3706, #3705) by @mwhooker
✨ New Features
FT.AGGREGATEwith support for repeated/interleavedLOAD,APPLY,GROUPBY, andSORTBYstages (#3782) by @ndyakovVISMEMBERandWITHATTRIBSsupport (#3753) by @romanpovolNewScriptServerSHAusesSCRIPT LOADto obtain the digest from the server, avoiding client-side SHA-1 (#3700) by @chaitanyabodlapatiDoRawandDoRawWriteTofor raw RESP protocol access (#3713) by @ofekshenawaDialerRetryBackofffunction option with constant and exponential helpers (#3706) by @mwhookerNOSCRIPTreplies are now surfaced as a typed error for easier handling (#3738) by @LINKIWIClientSetNamemethod toPubSub(#3727) by @Flack74ReplicaOfmethod replaces the deprecatedSlaveOf(#3720) by @CopilotHScannow supports types implementingencoding.BinaryUnmarshaler(#3768) by @Aaditya-dubey1🐛 Bug Fixes
CLIENT MAINT_NOTIFICATIONShandshake whenHELLOfails and connection falls back to RESP2; fail fast when explicitly enabled with RESP3 (#3788) by @ndyakovShouldRetrynow treatsnet.OpErrorwithOp == "dial"timeout errors as safe to retry since no command was sent (#3787) by @vladisa88baseClientclose logic; replaced with a bounded, concurrency-safe named-hook registry (#3785) by @ndyakovcloseNotifytimeouts) for connections already dropped by the server due to idle timeout (#3778) by @ofekshenawaConnStateMachine.notifyWaitersthat could wake multiple waiters under a single mutex hold and violate FIFO ordering (#3777) by @0x48coreREADONLYerrors embedded in Lua script error messages on read-only replicas so commands are correctly retried (#3769) by @zhengjileiVSimWithScores,VSimWithArgsWithScores, andVLinksWithScoreswhich were broken on RESP2 connections returning flat arrays instead of maps (#3767) by @CopilotZRangeArgswithRev+ByScore/ByLexincorrectly swappingStart/Stop, breakingZRANGESTORE(#3751) by @Copilotredisotel-native(#3743) by @ofekshenawaOptions(#3739) by @rubensayshiredisotel-native(#3735) by @ofekshenawaotel/semconv/v1.38.0inredisotel-native(#3731) by @wzy9607SET ... NXinstead of the deprecatedSETNXcommand (#3723) by @ndyakovTIMEas a keyless command for correct cluster routing (#3722) by @fatal10110pool.namebeing appended per node, which corrupted and dropped user-provided custom attributes (#3699) by @Jesse-Bonfire*baseClient.initConn(); added explicit nil option guards to client constructors (#3676) by @olde-ducke⚡ Performance
github.com/dgryski/go-rendezvousdependency with an in-repo implementation ininternal/hashtag, reducing the dependency graph while preserving algorithm parity (#3762) by @bigsk05🧪 Testing & Infrastructure
repository,ref, andclient-libs-test-image-taginputs to therun-testscomposite action;redis-versionis now optional so unstable builds useREDIS_VERSIONfrom the Makefile (#3749) by @dariaguy-compat=1.24in release scripts (#3714, #3754) by @ndyakov, @cxljs🧰 Maintenance
Conn.closedatomic field in favor of the state machine'sStateClosed(#3783) by @cxljsredisotel/redisotel-native(#3770) by @ndyakovmaps.Keys,slices.Collect,slices.Contains,clear(), andslices.SortFuncinstead of custom helpers (#3758, #3746) by @cxljsHGetAlldescribing behavior and complexity (#3776) by @0x48coreConfiguration
📅 Schedule: (UTC)
🚦 Automerge: Disabled by config. Please merge this manually once you are satisfied.
♻ Rebasing: Whenever PR is behind base branch, or you tick the rebase/retry checkbox.
🔕 Ignore: Close this PR and you won't be reminded about this update again.
This PR was generated by Mend Renovate. View the repository job log.