Repository navigation
fix(deps): update all non-major dependencies - #29
Open
renovate[bot] wants to merge 1 commit into
Open
renovate[bot] wants to merge 1 commit into
renovate[bot] wants to merge 1 commit into
Conversation
Contributor
Author
ℹ️ Artifact update noticeFile name: go.modIn order to perform the update(s) described in the table above, Renovate ran the
Details:
|
renovate
Bot
force-pushed
the
renovate/all-minor-patch
branch
3 times, most recently
from
February 10, 2026 21:13
b956a3a to
5989b17
Compare
renovate
Bot
force-pushed
the
renovate/all-minor-patch
branch
2 times, most recently
from
February 17, 2026 06:03
2ce1310 to
222bd2a
Compare
renovate
Bot
force-pushed
the
renovate/all-minor-patch
branch
4 times, most recently
from
March 2, 2026 17:01
db57d39 to
17467d4
Compare
renovate
Bot
force-pushed
the
renovate/all-minor-patch
branch
2 times, most recently
from
March 12, 2026 01:54
cfff61d to
5fff2ee
Compare
renovate
Bot
force-pushed
the
renovate/all-minor-patch
branch
from
March 16, 2026 09:26
5fff2ee to
de00e4b
Compare
renovate
Bot
force-pushed
the
renovate/all-minor-patch
branch
3 times, most recently
from
April 12, 2026 01:18
07ae4dd to
e333938
Compare
renovate
Bot
force-pushed
the
renovate/all-minor-patch
branch
from
April 28, 2026 15:35
e333938 to
96f344f
Compare
renovate
Bot
force-pushed
the
renovate/all-minor-patch
branch
3 times, most recently
from
May 12, 2026 17:26
6378906 to
987c87a
Compare
renovate
Bot
force-pushed
the
renovate/all-minor-patch
branch
2 times, most recently
from
May 28, 2026 10:33
e43494b to
41d6ec7
Compare
renovate
Bot
force-pushed
the
renovate/all-minor-patch
branch
from
July 26, 2026 01:55
41d6ec7 to
57ffd72
Compare
renovate
Bot
force-pushed
the
renovate/all-minor-patch
branch
5 times, most recently
from
August 10, 2026 08:33
b448393 to
b06275c
Compare
renovate
Bot
force-pushed
the
renovate/all-minor-patch
branch
from
August 12, 2026 19:37
b06275c to
7d7ddfe
Compare
renovate
Bot
force-pushed
the
renovate/all-minor-patch
branch
4 times, most recently
from
August 24, 2026 00:43
bd3207e to
9fa7b73
Compare
renovate
Bot
force-pushed
the
renovate/all-minor-patch
branch
16 times, most recently
from
September 1, 2026 20:04
7b4dc6f to
6443906
Compare
renovate
Bot
force-pushed
the
renovate/all-minor-patch
branch
5 times, most recently
from
September 8, 2026 22:39
801626b to
920bc19
Compare
renovate
Bot
force-pushed
the
renovate/all-minor-patch
branch
from
September 15, 2026 16:01
920bc19 to
2aecaed
Compare
renovate
Bot
force-pushed
the
renovate/all-minor-patch
branch
2 times, most recently
from
October 8, 2026 18:53
9af8721 to
b26ca17
Compare
renovate
Bot
force-pushed
the
renovate/all-minor-patch
branch
from
October 10, 2026 01:16
b26ca17 to
8ce594e
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:
v9.17.1→v9.23.0v1.0.68→v1.0.78v1.52.0→v1.53.0v1.9.3→v1.10.2v1.11.1→v1.12.11.25.4→1.27.2v0.47.0→v0.61.0v9.2.0→v9.3.0Release Notes
redis/go-redis (github.com/redis/go-redis/v9)
v9.23.0: 9.23.0Compare Source
This is a minor release. It contains everything from 9.23.0-beta.1, so these notes cover the full 9.22.0 → 9.23.0 upgrade.
godirective of the root module and of the submodules moved from1.24to1.26, as part of the dependency bumps forgovulncheckfindings. Projects that build with Go 1.24 or 1.25 must upgrade the toolchain.Clienthas a dedicated pipeline connection pool (#4002). This includes failover clients and cluster node clients.Pipeline,TxPipeline, and autopipeline operations use this pool, so they do not compete with regular commands for main-pool connections. The pool is for burst capacity only: it dials only when necessary, an unused pool holds zero connections, and if the pool is full an operation uses the main pool. SetPipelinePoolSize: -1to get the previous single-pool behavior.AutoPipelineOptions.MaxBatchByteshas a default of 128 KiB (before, there was no limit). The default prevents a write/reply deadlock; it is not a throughput control. The buffers of the pipeline pool also have a default of 128 KiB.AutoPipelineOptions.FullDuplexFastSubmitis removed (#4018). The submit channel is replaced by a queue that takes a full wave of commands in one lock, so the separate fast path is not necessary. Remove the field from your options.Options.ClientSideCacheRefreshRecencyWindowis removed (#4034). Refresh-on-invalidate now reads again every cached entry of an invalidated key and does not look at how recently the entry was read. On a write-heavy keyspace this means refresh traffic across the full resident cache. Remove the field from your options.LocalCache.LRUClock()is removed (#4034). It returned the recency token that the removed recency window used, and has no replacement. Remove calls to it.ClientSideCacheInvalidationBatchWindowserved stale values in beta.1 (#4033). Under load the batcher applied only ~15% of invalidations, and the cache served invalidated values with a ~100% hit rate. 9.23.0 applies all of them. If you used this option on beta.1, upgrade.🚀 Highlights
Full-Duplex Auto-Pipelining (Experimental)
Set
AutoPipelineOptions.FullDuplexto enable the full-duplex mode of the automatic pipeliner. The default mode sends one batch per round trip. In full-duplex mode the engine holds one pipeline-pool connection, and a writer goroutine and a reader goroutine move the ordered command stream in both directions at the same time. On a high-latency link each command completes in approximately one round-trip time (RTT) on a single connection. On a 50 ms WAN profile: ~389k ops/s at 52 ms p50, against ~207k ops/s at 116 ms on the half-duplex ordered path.The mode works on both faces of a standalone
Client(AutoPipeline()andAsyncAutoPipeline()), and natively on aClusterClientwhen routing goes to masters only. On a cluster, one child engine per master sends each command to the node that owns its slot, and followsMOVED/ASKredirects and retryable replies (LOADING,READONLY, ...) through the usual cluster redirect path. With replica routing (ReadOnly,RouteByLatency, orRouteRandomly), the autopipeliner uses the half-duplex shard flushers, which obey the shard picker.Config().FullDuplexreports the mode in effect.Options:
FullDuplexWindow— the maximum number of commands in flight (backpressure).FullDuplexIdleTimeoutandFullDuplexMaxHold— when the engine returns the held connection to the pool. The pool hooks then do re-authentication and maintenance-notification handoffs.MaxFlushDelay— now also used in full-duplex mode (#4014). The writer waits only when enough commands are in flight, so low-concurrency callers keep the 1×RTT behavior. WithMaxFlushDelay=250µsat 1024 callers: +22% ops/s and −26% p99. The default is 0, so this is opt-in.NumShards— on a standaloneClient, the number of full-duplex engines (#4022). See below.Pipeline()on the full-duplex connection (#4021). StandaloneClientonly. Before,ap.Pipeline()used a pooled connection for eachExec. It now submits the batch to the engine as one contiguous run (FDPipelined), so replies come back in submit order, as on a dedicated connection. At 256–1024 callers with 10 commands perExec: +49% to +52% throughput on one socket instead of ~150. Errors, retries, hooks, and metrics behave like an ordinary pipeline. A batch that cannot use the stream (a blocking command, a per-command read timeout, a diverted command, or a batch larger than the queue) falls back to the ordinary pipeline.TxPipelinestays on a pooled connection, becauseMULTI/EXECneeds connection affinity. On aClusterClient,ap.Pipeline()is still the ordinary cluster pipeline. A batch that the queue cannot admit now reserves its slots and waits in a first-come line, so single commands cannot starve a long pipeline (#4057, merged as part of #4021) by @vlady-kotsev.Several engines on one client (#4022). With
FullDuplex,NumShards > 1now means N engines on one client: one pool, one hook chain, N held connections. Commands route by a hash of their first key, so commands on the same key stay on one connection and keep their order withoutUnordered. Keyless commands are distributed round-robin. AnFDPipelinedbatch stays on one engine. The pipeline pool must hold at leastNumShardsconnections for each full-duplex autopipeliner. More engines help only under high concurrency: with 10-command pipelines, 8 engines were 30% slower than 1 at 8 callers, equal at about 128 callers, and 2.2× faster at 1024 callers.The full-duplex path supports blocking commands,
Options.Limiter(one admission per written batch), per-command and pipeline hooks, OTel metrics, retry budgets (aNoRetrycommand is never sent again after it is on the wire), and seamless maintenance handoffs. Limits of the stream model:ProcessHookthat returns without callingnextdoes not cancel the command on the full-duplex path; the command is already queued on the held connection. Run policy or kill-switch hooks on a plain client or on the half-duplex autopipeliner.HIMPORTcommands. On the async face, wait for the result of a diverted command before you submit a command that depends on it.Runnable examples:
example/autopipeline(all faces),example/autopipeline-fullduplex(blocking face,Pipeline()andFDPipelined), andexample/autopipeline-fullduplex-async(async face,Submit,NumShards) (#4061).Experimental: the auto-pipelining APIs can change in a minor release.
(#4002, #4014, #4018, #4021, #4022) by @ndyakov
Client-Side Caching: Refresh-on-Invalidate, Miss Coalescing, Faster Reads
Two new functions for the experimental shared-tracking client-side cache. They have no effect unless CSC is enabled (#3989) by @ndyakov:
Options.ClientSideCacheRefreshOnInvalidate): when an invalidation push arrives, the client reads every cached entry of that key again in the background, so the next reader does not pay the miss. Each invalidation of a cached key costs one background read.ClientSideCacheInvalidationBatchWindowcollects invalidation-driven deletes into background batches; without it, the connection reader applies each delete inline.Options.ClientSideCacheCoalesceMisses): concurrent cache misses are pipelined on one tracked connection. Each miss keeps its own per-key command (no rewrite toMGET), so it is safe on a cluster. Each reply is written to the cache with the connection's tracking generation, so the server can invalidate it.Both options need the built-in cache (
ClientSideCacheConfig, orClientSideCacheset to a*LocalCache). With a customCacheimplementation they are ignored.The cache read path is also faster (#4034, #4035, #4036, #4037) by @ndyakov. A hit no longer writes a timestamp to the entry; a second-chance bit marks reads, and is set only under eviction pressure. The cache key is built in pooled scratch memory, the key list is built only on a miss, and nil/status/bulk-string hits are decoded without allocation. Against 9.23.0-beta.1 on a warm cache: +18% to +57% reads/s from 4 to 1024 callers, p50 from 2.6–5.4 µs to 1.0–1.5 µs, with identical hit rates and 100% of invalidations applied.
Better Distribution for Latency-Based Cluster Read Routing
RouteByLatencyselects the node with the strictly minimum latency. The measurement has noise (the mean of ten pings, refreshed at most every 10 s), so all clients can select the same node from a set of nodes with almost equal latency. In one production system, GET rates across five replicas in one availability zone had a 590× spread.The new
ClusterOptions.RouteByLatencyTolerancewidens the selection to every node within the tolerance of the fastest node, and distributes reads across them round-robin with theShardPicker. A node in a different availability zone stays outside a sensible tolerance, so zone locality is kept. The default is zero (strict minimum). The option is also onFailoverOptions, for clients fromNewFailoverClusterClient; the plainNewFailoverClientdoes not support latency routing. (#3973) by @jozenstarThe same work fixed a routing defect: the client recorded the nearest healthy node only when that node was also the fastest overall. A node that fails fast (for example, a refused connection) hid every healthy node, and reads went to the failing node. The client now records the healthy minimum separately. (#3994) by @jozenstar
EphemeralConnfor Session-Scoped WorkClient.Conn()returns its connection to the parent pool onClose. If you ranAUTHorSELECTon it, later commands on the pooled client run as that ACL user and in that DB. The newClient.EphemeralConn()returns the same sticky connection, butCloseremoves it from the pool instead. The cost is one dial perEphemeralConn.Client.Conn()is unchanged. (#4039) by @saddamr3e✨ New Features
AutoPipelineOptions.FullDuplex, withFullDuplexWindow/FullDuplexIdleTimeout/FullDuplexMaxHold, on standalone and cluster clients (#4002) by @ndyakovPipeline()on the full-duplex connection:ap.Pipeline()andFDPipelinedsubmit a batch to the engine as one contiguous run, on a standaloneClient(#4021) by @ndyakovNumShards > 1withFullDuplexon a standaloneClient, with key-hash routing (#4022) by @ndyakovAutoPipelineOptions.MaxQueuedCommands: an opt-in hard limit on accepted, not-yet-completed autopipeline commands. At the limit a command fails immediately withErrAutoPipelineQueueFull, so memory does not grow without limit when the server is slow. WithFullDuplex, the ordered stream is bounded byFullDuplexWindowinstead (a full window blocks the submitter, it does not reject), andMaxQueuedCommandslimits only the commands that run outside the stream (blocking, connection-hostile,Do). The default0means no limit (#4070) by @ndyakovPipelinePoolSizehas a default ofDefaultPipelinePoolSize(10) on each client. If the pool is full, an operation uses the main pool. Set-1to disable the pool (#4002, #3959) by @ndyakovOptions.ClientSideCacheRefreshOnInvalidate(withClientSideCacheInvalidationBatchWindow) andOptions.ClientSideCacheCoalesceMisses(#3989) by @ndyakovClient.EphemeralConn: a sticky connection that is removed from the pool onClose, for session-scopedAUTH/SELECTwork (#4039) by @saddamr3eRouteByLatencyTolerance: distributes reads across nodes with almost equal latency, on cluster clients and onNewFailoverClusterClient(#3973) by @jozenstarAutoPipeliner.WaitClosed: blocks until the drain of accepted commands completes, and returns the drain result. Use it in a wrapper that must not close shared pools during a flush (#3998) by @ndyakovredisotel-nativeWithRecordNilErrors: opt in to countredis.Nilreplies as client errors (see the fix below) (#4025) by @lazergCMSInfo.CellSize: the cell-size field ofCMS.INFOin Redis 8.12 (#4010) by @elena-kolevska🐛 Bug Fixes
ClientSideCacheInvalidationBatchWindowapplied only ~15% of invalidations under load, so the cache served stale values with a ~100% hit rate. Each batch now takes each shard lock once, and 100% of invalidations are applied (#4033) by @ndyakovPutdid not wake a worker that waited for a connection to becomeIDLE, so a streaming-credentials re-auth could stall untilPoolTimeoutand then close the connection (#4028) by @avitenzer. Two related waiter-queue races are fixed: a failed transition left a dead waiter queued, which later moved a connection toUNUSABLEfor nobody (#4072) by @ndyakovBitOp*,MIGRATE,OBJECT ENCODING/FREQ/IDLETIME/REFCOUNT,XINFO STREAM/GROUPS/CONSUMERS,LMPOP,BLMPOP,SINTERCARD,ZINTERCARD,ZMPOP,BZMPOP) routed by the wrong argument. On aRingthey went to the wrong shard; on a cluster they cost an extraMOVEDround trip. A rawFCALL/FCALL_ROhashed the function name. All now route by their key (#4048) by @ndyakov. RawXGROUP,ZUNION/ZINTER/ZDIFF,SDIFFCARD/SUNIONCARD,TS.NRANGE/TS.NREVRANGE, andHIMPORT SETforms are also fixed (#4022)PExpireAt,HPExpireAt, andHPExpireAtWithArgsoverflowed for dates outside the nanosecond range (for example, year 2270), so Redis deleted the key or rejected the command (#4026) by @jakezwang.SetArgs.ExpireAtnow sendsPXATwhen the deadline has millisecond precision; before,EXATdropped the milliseconds (#4053) by @LindseyZ1205-1timeouts: a-1read/write timeout onClusterOptionsgave node clients the 5 s default instead of no timeout (fixes #4049) (#4050) by @lazergredis.Nilas error: a cache miss (redis.Nil) incrementedredis.client.errorsand was tagged as a server error ondb.client.operation.duration. Nil replies are now classifiedNILand not counted, unlessWithRecordNilErrors(true)is set (fixes #4024) (#4025) by @lazergSENTINEL SET ... auth-passis now redacted in command rendering (used byredisotel/rediscensusspan attributes), and aMIGRATEpassword with the literal valueauth/auth2is redacted at the correct position (#4011) by @saddamr3eAggMinAggregator/AggMaxAggregatorpanic instead of returning an error fromResult()(#4056) by @SuselzParseURLskip_verify: an invalid value (for example,skip_verify=yes) was silently treated asfalse.ParseURLandParseFailoverURLnow return an error, like for the other boolean options (#4064) by @orinnzuintptrarguments:uintptrand*uintptrare now encoded like the other unsigned integers; a nil*uintptris encoded as0(fixes #3100) (#4054) by @yamaankhan20*.INFOforward compatibility: theBF.INFO/CF.INFO/CMS.INFO/TOPK.INFO/TDIGEST.INFOparsers skip unknown fields instead of returning an error. Redis 8.12 addscell sizetoCMS.INFO(#4010) by @elena-kolevskaNewClientpanic leak: a panic during construction (for example, a maintnotifications failure inModeEnabled) does not leak the connection pools that already exist, and a typed-nil pool cannot hide the initial panic (#4003) by @ndyakov. The same guards apply toNewFailoverClient(#4002)Conn.Closedoes the socket teardown and the unsubscribe/CSC callbacks when the connection is alreadyCLOSED. Before, init and auth failures leaked open descriptors (fixes #3982) (#3985) by @ndyakovLoggerandLogLevel, and call-site attribution is correct again (#3988) by @saddamr3eConn.onClosedata race: the close hooks that init installs (onCloseandonCscClose) are atomic against a concurrentClose(#3966) by @saddamr3eFTHybridCmdreads the full RESP3 map reply without desynchronizing the connection (#3956) by @saddamr3eCLIENT INFOforward compatibility: the parser skips unknown client-flag characters instead of failing the reply (#3977) by @ndyakovGEOSEARCHduplicate args: the command no longer sends duplicate arguments (#3955) by @mehmettokgozMSetEXcluster routing: the constructor sets the first-key position, so typed calls go to the correct slot (#3984) by @shivamrustagiClose: a concurrentClosedoes not block (no re-entrant deadlock), andWaitClosedreturns the drain result (#3998) by @ndyakovisHealthyConnis logged only at debug level, so CSC invalidations do not fill the log (#3948) by @ndyakovPipeline/TxPipelinepath removes the connection instead of returning a desynchronized connection to the pool (#4002) by @ndyakov⚡ Performance
MaxFlushDelay: opt-in write coalescing under load. With 250 µs at 1024–2048 callers: +22% to +25% ops/s and −26% to −29% p99; 30% less CPU at 256 callers (#4014) by @ndyakovScangets zero-copy semantics, and the RESP reader skips unnecessary data conversions (#3972) by @vlady-kotsev🧪 Testing & Infrastructure
govulncheckdependency bumps: the minimum Go version is 1.26, CI defaults to 1.26, and a newgo-versionsjob builds the test matrix fromgo.modplusoldstable/stable(#4060) by @vlady-kotsevPinggate, which removes ~1.6 min of dial-retry waits when the full stack is not running (#4001) by @ndyakovCLIENT INFOtracking-flag assertion is skipped behind the RE proxy (#3981) by @ndyakovUniversalOptionsdocumentsReadTimeout/WriteTimeout/ContextTimeoutEnabled(#4047) by @lazerg; the README describesDisableIdentityas client identification (CLIENT SETINFO), not identity verification (#4059) by @FanWu-ai👥 Contributors
We thank all the contributors who worked on this release!
@avitenzer, @elena-kolevska, @FanWu-ai, @jakezwang, @jozenstar, @lazerg, @LindseyZ1205, @mehmettokgoz, @ndyakov, @orinnz, @Phalanyx, @saddamr3e, @shivamrustagi, @Suselz, @vlady-kotsev, @yamaankhan20
Full Changelog: redis/go-redis@v9.22.0...v9.23.0
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](https://redirect.github.com/redis/go-redisConfiguration
📅 Schedule: (UTC)
* 0-3 1 * *)🚦 Automerge: Enabled.
♻ Rebasing: Whenever PR is behind base branch, or you tick the rebase/retry checkbox.
👻 Immortal: This PR will be recreated if closed unmerged. Get config help if that's undesired.
This PR was generated by Mend Renovate. View the repository job log.