-
Project Reactor is no longer needed for the synchronous and asynchronous APIs.
reactor-coreis still a dependency oflettuce-core, but applications that use onlysync()/async()can exclude it. The parts that still need Reactor are:- the reactive API (
reactive(),commands(...ReactiveCommands.factory())); - the Kotlin coroutines API;
- the deprecated
RedisCredentialsProvider.
Internally, connection setup, reconnection, Sentinel and Master/Replica topology discovery, the event bus and trace-context propagation no longer use Reactor. When compiling without Reactor on the classpath, pass a typed
CredentialsProvidertoRedisURI.setCredentialsProvider(...)andRedisURI.Builder.withAuthentication(...), for example a variable, a cast,CredentialsProvider.from(...)orStaticCredentialsProvider. A bare lambda doesn't compile, because the compiler needs Reactor to choose between those methods' two overloads. - the reactive API (
-
connectAsync(...)failures now report the original cause and message, asconnect(...)does. Previously the asynchronous path could surface aRedisConnectionExceptionwith anullmessage that wrapped aCompletionException. -
RESP3 replies are now decoded the same way inside transactions and on Pub/Sub connections as on regular connections. On a Pub/Sub connection, a command that returns a RESP3 boolean no longer fails with
UnsupportedOperationException. Some RESP3 map and set replies whose first element ismessageorpmessageare no longer mistaken for Pub/Sub messages. Before, such a reply went to the Pub/Sub listeners and the command never completed.
Lettuce 8.0 removes the Reactor-based APIs deprecated in 7.8 and 7.9, and changes the Reactor-typed extension points that subclasses and custom implementations use.
-
Event bus:
EventBus.get(), which returned aFlux<Event>, is removed. Usesubscribe(Consumer)orsubscribe(Class, Consumer), which return aSubscription; see Events for bridging to aFlux.EventBus.subscribe(Consumer)is now abstract, so customEventBusimplementations must implement it.DefaultEventBus(Scheduler)is replaced byDefaultEventBus(EventExecutorGroup)andDefaultEventBus(EventExecutorGroup, int).
-
Tracing:
TraceContextProvider.getTraceContextLater()is removed. ImplementgetTraceContextAsync(Map)instead.Tracing.getContext(),Tracing.clearContext()andTracing.withTraceContextProvider(TraceContextProvider)are removed. Use the methods of the same names onAbstractRedisReactiveCommands.ReactorTraceContext.
-
Reactive accessors:
-
reactive()remains available on all stateful connection interfaces as a deprecated default method that delegates tocommands(...)with the matching*ReactiveCommands.factory(). -
The connection implementations no longer hold a reactive API instance. Removed:
- the protected
reactivefields; - the
newRedisReactiveCommandsImpl()factory methods onStatefulRedisConnectionImpl,StatefulRedisPubSubConnectionImplandStatefulRedisClusterPubSubConnectionImpl; newRedisAdvancedClusterReactiveCommandsImpl()onStatefulRedisClusterConnectionImpl.
Subclasses that override these methods are no longer called; obtain a custom reactive API through
commands(CommandsFactory)instead. - the protected
-
commands(CommandsFactory)is now abstract onStatefulRedisConnection,StatefulRedisClusterConnection,StatefulRedisPubSubConnection,StatefulRedisClusterPubSubConnectionandStatefulRedisSentinelConnection, so custom implementations of these interfaces must implement it.
-
-
Credentials:
StaticCredentialsProviderandTokenBasedRedisCredentialsProviderimplement onlyCredentialsProvider. They no longer implementRedisCredentialsProvider,resolveCredentials()orcredentials(). UseresolveCredentialsAsync()andsubscribeToCredentials(...), or wrap a provider withRedisCredentialsProvider.adapt(...)where aRedisCredentialsProvideris required.- The deprecated
RedisURI.getCredentialsProvider()returns such providers wrapped in an adapter, so don't cast its result to a concrete provider type. The adapter of an immediate provider such asStaticCredentialsProvideris still aRedisCredentialsProvider.ImmediateRedisCredentialsProvider, so code that checks for that interface and callsresolveCredentialsNow()keeps working. Otherwise useRedisURI.getCredentialsProviderAsync(). See Authentication. ConnectionState.getCredentialsProvider()andConnectionState.setCredentialsProvider(RedisCredentialsProvider)are removed in favor ofgetCredentialsProviderAsync()andsetCredentialsProvider(CredentialsProvider).- On
RedisAuthenticationHandler, the constructor andcreateHandler(...)variants that take aRedisCredentialsProviderare removed, as arecomplete()andonNext(RedisCredentials).
-
Connection extension points: these now use
Supplier<CompletionStage<SocketAddress>>instead ofMono<SocketAddress>:RedisClient.getSocketAddress(RedisURI);RedisClusterClient.getSocketAddressSupplier(...);AbstractRedisClient.connectionBuilder(...);ConnectionBuilder.socketAddressSupplier(...)andsocketAddress();- the
ConnectionWatchdogandMaintenanceAwareConnectionWatchdogconstructors and theirwrapSocketAddressSupplier(...).
The watchdog constructors also no longer take a
ConnectionFacade. -
RESP3 map replies in transactions: inside
MULTI/EXECon a RESP3 connection, commands whose result is built from the RESP3 reply types now return a RESP3 map reply as aMap, the same as outside a transaction. Before, they returned a flatListof keys and values. This affectsEVAL,EVALSHAandFCALL(and their read-only variants) withScriptOutputType.OBJECT,FUNCTION LIST,CLUSTER LINKS, anddispatch(...)with anObjectOutput. Code that casts theseTransactionResultentries toListmust handle aMapinstead. RESP2 connections are not affected.
- Introduced a reactor-free credentials SPI:
CredentialsProviderresolves credentials as aCompletionStageviaresolveCredentialsAsync()and no longer requires Project Reactor. It adds afrom(Supplier)factory and a nestedImmediateCredentialsProvider(resolveCredentialsNow()) for synchronous resolution, and supports streaming credentials through the callback-basedsubscribeToCredentials(Consumer<RedisCredentials>, Consumer<Throwable>)that returns anio.lettuce.core.Subscription.RedisURInow stores aCredentialsProviderand exposesgetCredentialsProviderAsync(),setCredentialsProvider(CredentialsProvider)andBuilder.withAuthentication(CredentialsProvider). The reactiveRedisCredentialsProvider(returningMonothroughresolveCredentials()/credentials()) now extendsCredentialsProviderand is deprecated; the reactiveRedisURIaccessors are retained as compatibility shims, so existing code keeps working.RedisCredentialsProvider.adapt(CredentialsProvider)wraps aCredentialsProviderfor APIs that still require aRedisCredentialsProvider, such as a Spring Data RedisRedisCredentialsProviderFactory, and keeps streaming. An adaptedCredentialsProvider.ImmediateCredentialsProviderstays aRedisCredentialsProvider.ImmediateRedisCredentialsProvider. - Deprecated the Reactor-based
resolveCredentials()ofStaticCredentialsProviderandresolveCredentials()/credentials()ofTokenBasedRedisCredentialsProviderin favor ofresolveCredentialsAsync(),resolveCredentialsNow()andsubscribeToCredentials(...), which don't require Project Reactor. - Deprecated the
Mono-based connection extension points used by subclasses and custom connection plumbing: bothAbstractRedisClient.connectionBuilder(...)overloads,RedisClient.getSocketAddress(RedisURI),RedisClusterClient.getSocketAddressSupplier(...), and theConnectionWatchdogandMaintenanceAwareConnectionWatchdogconstructors and theirwrapSocketAddressSupplier(...). Their signatures change in the next major release; there is no replacement yet.
- Fixed
LCSfor non-Stringkey codecs and Redis Cluster through the newlcs(key1, key2)andlcs(key1, key2, LcsArgs)overloads on the sync, async, reactive, cluster node-selection and Kotlin APIs. The keys are now passed as regular key arguments, so they are encoded through the key codec and participate in cluster slot routing;lcs(key1, key2)returns the longest common substring asV.LcsArgs.Buildergained key-less entry points (justLen(),withIdx(),minMatchLen(…),withMatchLen()). Deprecatedlcs(LcsArgs),LcsArgs.Builder.keys(…)andLcsArgs.by(…), which encode the keys as plain strings and do not participate in slot routing - Support for the unified
ZRANGEsyntax introduced in Redis 6.2 through newzrangeandzrangeWithScoresoverloads (list-returning, plus streaming-channel variants on the sync and async APIs) accepting aZRangeselector:ZRange.byIndex(start, stop),ZRange.byScore(range)(BYSCORE) orZRange.byLex(range)(BYLEX). Each selector exposes only the options the server accepts for its kind —rev()on all three,limit(...)on score and lexicographical ranges — andzrangeWithScoreshas no lexicographical overload becauseBYLEXcannot be combined withWITHSCORES, so illegal combinations do not compile. Available in the sync, async, reactive, cluster node-selection and Kotlin APIs — a single entry point covering theZREVRANGE,ZRANGEBYSCORE,ZREVRANGEBYSCORE,ZRANGEBYLEXandZREVRANGEBYLEXvariants - Deprecated the sorted-set range commands that Redis 6.2 superseded with the unified
ZRANGEsyntax:zrangebylex,zrangebyscore,zrangebyscoreWithScores,zrevrange,zrevrangeWithScores,zrevrangebylex,zrevrangebyscoreandzrevrangebyscoreWithScores(all overloads, including the streaming-channel variants) on the sync, async, reactive and cluster node-selection APIs. Each@deprecatednote names thezrange/zrangeWithScoresoverload andZRangeselector option (rev(),limit(...)) that replaces it. The Kotlin coroutine API no longer exposes these commands; use theZRange-basedzrange/zrangeWithScoresfunctions instead - Deprecated the server-assisted client-side caching support (
ClientSideCaching,CacheFrontend,CacheAccessor,RedisCacheinio.lettuce.core.support.caching). This implementation is legacy and incomplete and is scheduled for removal in a future major release. There is no replacement yet — a redesigned client-side caching API is planned. - Fixed
ScriptOutputType.OBJECTdecoding so top-level scalar responses are returned directly instead of being treated as collections. Top-level integer responses now returnLonginstead of a one-elementList<Long>; RESP arrays remain lists. - Fixed
XAUTOCLAIMreply decoding for pending entries that were deleted from the stream (the third reply element added in Redis 7.0). WithJUSTID, those deleted IDs are no longer misreported as claimed messages throughClaimedMessages.getMessages(); they are now exposed through the newClaimedMessages.getDeletedIds(), which returns an empty list on Redis before 7.0. - Began making Project Reactor an optional dependency for the client's public API. Added
commands(CommandsFactory)on the stateful connection interfaces (StatefulRedisConnectionand the cluster, pub/sub and sentinel variants), which returns a command API bound to the connection and cached per factory. Command APIs now expose a staticfactory()— for exampleRedisReactiveCommands.factory()— so the reactive API can be obtained viaconnection.commands(RedisReactiveCommands.factory()). Thereactive()accessor is deprecated in favor of this factory-based accessor. - Deprecated the Reactor-based
EventBus.get()(which returns aFlux<Event>) in favor of a callback-based subscription API:EventBus.subscribe(Consumer<Event>)andEventBus.subscribe(Class<T>, Consumer<T>), each returning anio.lettuce.core.Subscriptionthat is closed to stop delivery. This lets event consumers avoid a direct dependency on Project Reactor. - Deprecated the Reactor (
Mono) parts of the tracing SPI:TraceContextProvider.getTraceContextLater()(returningMono<TraceContext>) is deprecated in favor of the callback-basedgetTraceContextAsync(...), removing Project Reactor from the trace-context propagation path used by customTraceContextProviderimplementations.
- Probabilistic data structures (RedisBloom) support through
RedisBloomFilterCommands,RedisCuckooFilterCommands,RedisTopKCommands,RedisCMSCommandsandRedisTDigestCommands, with the respective async, reactive and Kotlin APIs — covering Bloom Filter (BF.*), Cuckoo Filter (CF.*), Top-K, Count-Min Sketch and T-Digest - Support for the
HIMPORTcommand family for bulk-loading hashes that share the same field names, declaring the field names once per connection and sending only values per hash — see Hash Import - Support for the
SUNIONCARDandSDIFFCARDset cardinality commands - Support for the
LMOVEMandBLMOVEMmulti-element list move commands - Support for the
MAXCOUNTandMAXSIZEoptions onXREADandXREADGROUP - Support for
FT.ALIASLISTto list search index aliases - Support for the
VISMEMBERVector Set command — see Redis Vector Sets - Support for
CLIENT NO-TOUCHto control key access-time updates per connection
- Support for
FT.HYBRIDcommand enabling hybrid vector and full-text search queries - Ability to expose upstream driver libraries in
CLIENT SETINFOpayload for better client identification
- Support for
XREADGROUPwithCLAIMargument for atomic message claiming in Redis Streams consumer groups - Compare-and-Set (CAS) / Compare-and-Delete (CAD) commands through
DIGEST,DELEXandSETextensions for optimistic locking patterns - Support for
MSETEXcommand to atomically set multiple keys with expiration
- Maintenance events support for graceful handling of Redis maintenance operations enabling hitless upgrades
- Upgrade to Netty 4.2 with adaptive memory allocator and improved threading model
- RediSearch cluster mode support with cursor sticking and read operation distribution across nodes
- String-based JSON API to avoid unnecessary byte-to-string conversions
- Removal of deprecated APIs as part of major version cleanup
- RediSearch support through
RediSearchCommandsand the respective reactive, async and Kotlin APIs
- VectorSet support through
RedisVectorSetCommandsand the respective reactive, async and Kotlin APIs ConnectionPoolSupportalso allows the user to provide custom connection validations
- Support
HGETDEL,HGETEXandHSETEX - Introduce command replay filter to avoid command replaying after reconnect
- Deprecate the STRALGO command and implement the LCS in its place
- Token based authentication integration with core extension
- RedisJSON support through
RedisJSONCommandsand the respective reactive, async and Kotlin APIs - Complete support for all
CLUSTERcommands (addedCLUSTER MYSHARDIDandCLUSTER LINKS) - Added support for the
CLIENT TRACKINGcommand - Migrated the documentation to MkDocs
- Hash Field Expiration is now fully supported
- Sharded Pub/Sub is now fully supported
- Support
CLIENT KILLwith[MAXAGE]parameter andHSCANwithNOVALUESparameter
-
Redis Function support (
fcallandFUNCTIONcommands). -
Support for Library Name and Version through
LettuceVersion. Automated registration of the Lettuce library version upon connection handshake. -
Support for Micrometer Tracing to trace observations (distributed tracing and metrics).
-
RedisCredentialsProviderabstraction to externalize credentials and credentials rotation. -
Retrieval of Redis Cluster node connections using
ConnectionIntentto obtain read-only connections. -
Master/Replica now uses
SENTINEL REPLICASto discover replicas instead ofSENTINEL SLAVES.
-
Kotlin Coroutines support for
SCAN/HSCAN/SSCAN/ZSCANthroughScanFlow. -
Command Listener API through
RedisClient.addListener(CommandListener). -
Micrometer support through
MicrometerCommandLatencyRecorder. -
Configuration of extended Keep-Alive options through
KeepAliveOptions(only available for some transports/Java versions). -
Configuration of netty's
AddressResolverGroupthroughClientResources. UsesDnsAddressResolverGroupwhennetty-resolver-dnsis on the classpath. -
Add support for Redis ACL commands.
-
Support for RESP3 usage with Redis 6 along with RESP2/RESP3 handshake and protocol version discovery.
-
ACL authentication using username and password or password-only authentication.
-
Cluster topology refresh is now non-blocking.
-
RxJava 3 support.
-
Refined Scripting API accepting the Lua script either as
byte[]orString. -
Connection and Queue failures now no longer throw an exception but properly associate the failure with the Future handle.
-
Removal of deprecated API including timeout methods accepting
TimeUnit. Use methods acceptingDurationinstead. -
Lots of internal refinements.
-
xpendingmethods return nowList<PendingMessage>andPendingMessages -
Spring support removed. Use Spring Data Redis for a seamless Spring integration with Lettuce.
-
AsyncConnectionPoolSupport.createBoundedObjectPool(…)methods are now blocking to await pool initialization. -
DecodeBufferPolicyfor fine-grained memory reclaim control. -
RedisURI.toString()renders masked password. -
ClientResources.commandLatencyCollector(…)refactored intoClientResources.commandLatencyRecorder(…)returningCommandLatencyRecorder.
-
Improved SSL configuration supporting Cipher suite selection and PEM-encoded certificates.
-
Fixed method signature for
randomkey(). -
Un-deprecated
ClientOptions.pingBeforeActivateConnectionto allow connection verification during connection handshake.
-
Allow randomization of read candidates using Redis Cluster.
-
SSL support for Redis Sentinel.
-
Add support for
ZPOPMIN,ZPOPMAX,BZPOPMIN,BZPOPMAXcommands. -
Add support for Redis Command Tracing through Brave, see Configuring Client resources.
-
Add support for Redis Streams.
-
Asynchronous
connect()for Master/Replica connections. -
Asynchronous Connection Pooling through
AsyncConnectionPoolSupportandAsyncPool. -
Dedicated exceptions for Redis
LOADING,BUSY, andNOSCRIPTresponses. -
Commands in at-most-once mode (auto-reconnect disabled) are now canceled already on disconnect.
-
Global command timeouts (also for reactive and asynchronous API usage) configurable through Client Options.
-
Host and port mappers for Lettuce usage behind connection tunnels/proxies through
SocketAddressResolver, see Configuring Client resources. -
SCRIPT LOADdispatch to all cluster nodes when issued throughRedisAdvancedClusterCommands. -
Reactive
ScanStreamto iterate over the keyspace usingSCANcommands. -
Transactions using Master/Replica connections are bound to the master node.
-
New artifact coordinates:
io.lettuce:lettuce-coreand packages moved fromcom.lambdaworks.redistoio.lettuce.core. -
Reactive API now Reactive Streams-based using Project Reactor.
-
Redis Command Interfaces supporting dynamic command invocation and Redis Modules.
-
Enhanced, immutable Key-Value objects.
-
Asynchronous Cluster connect.
-
Native transport support for Kqueue on macOS systems.
-
Removal of support for Guava.
-
Removal of deprecated
RedisConnectionandRedisAsyncConnectioninterfaces. -
Java 9 compatibility.
-
HTML and PDF reference documentation along with a new project website: https://redis.github.io/lettuce/.