Stable Release in branch 8.8
8.8.1
Released 23 Jul 2026
(15 days ago)
SoftwareRedis
Version8.8
Status
Supported
Initial release8.8.0
25 May 2026
(2 months ago)
Latest release8.8.1
23 Jul 2026
(15 days ago)
Support statusYes
Source codehttps://github.com/redis/redis/tree/8.8.1
Documentationhttps://redis.io/docs/
Downloadhttps://download.redis.io/releases/
Redis 8.8 ReleasesView full list
Category Highlights
New Features Array data structure; INCREX window counter rate limiter; XNACK stream command; COUNT aggregator for ZUNION/ZINTER/ZUNIONSTORE/ZINTERSTORE; JSON.SET FPHA argument; multiple aggregators in a single TS.RANGE/REVRANGE/MRANGE/MREVRANGE call; FT.HYBRID KNN shard candidate limit argument; FT.PROFILE HYBRID support; subkey (field-level) hash notifications
Improvements General performance improvements; memory tracking now toggleable at runtime in non-clustered mode
Bug Fixes INCREX syntax correction; cluster topology change handling during multi-shard commands (MOD-14439); RedisBloom memory leak on RDB load (MOD-15418)

What is the new Array data structure in Redis 8.8 and when should you use it?

Redis 8.8 ships a first-class Array data type, contributed by Redis creator Salvatore Sanfilippo (@antirez), giving you ordered, index-accessible sequences as a native value type separate from Lists and Sorted Sets. In practice, Array fills the gap for use cases that need dense, positionally-addressed storage without the overhead of sorted set scores or the FIFO/LIFO semantics of Lists.

This matters if you are storing things like time-bucketed metrics, fixed-width sliding windows, or ordered tuples where random reads by index are the hot path. Lists require O(n) traversal for arbitrary index access; Array is designed to do better. Watch out for memory profiling on large arrays in the initial release and monitor your MEMORY USAGE output before rolling this out at scale.

# Store a fixed-size ordered sequence
ARRAY.SET myarray 0 "alpha"
ARRAY.SET myarray 1 "beta"
ARRAY.SET myarray 2 "gamma"

# Random index access
ARRAY.GET myarray 1
# "beta"

How does INCREX simplify rate limiting in Redis 8.8?

INCREX is a single atomic command that combines counter increment, optional bounds enforcement, and key expiration into one round-trip, replacing the multi-command patterns teams previously had to script with Lua or pipeline manually.

Before Redis 8.8, a typical sliding-window rate limiter required at least a MULTI/EXEC block or a Lua script wrapping INCR, a bounds check, and EXPIRE. With INCREX you express all of that in one command. This matters if you are running high-throughput API gateways where each extra round-trip is latency you cannot afford.

# Increment a counter by 1, cap at 100, expire the key after 60 seconds
# Returns the new value, or an error if the bound would be exceeded
INCREX api:user:42:requests 1 MAX 100 EX 60

# Fractional increments (INCRBYFLOAT semantics) also supported
INCREX score:player:7 0.5 MAX 9999.99 EX 3600

Note the syntax was corrected between RC1 and GA (fix #15237) -- if you evaluated INCREX on the release candidate, re-read the current docs before deploying.

What does XNACK add to Redis Streams and how is it different from XACK?

XNACK lets a consumer explicitly release a pending message back to the stream's pending entry list without acknowledging it, signaling to the group that the message was not processed and should be re-delivered or picked up by another consumer.

Before this command, the only clean escape hatch when a consumer could not process a message was to let the idle time tick up and rely on another consumer calling XAUTOCLAIM or XCLAIM after a timeout. That meant you were always racing against a timer. Most teams that built robust consumer groups had to implement application-level negative acknowledgment with workarounds; XNACK makes this a first-class protocol primitive.

# Consumer reads a message
XREADGROUP GROUP mygroup consumer1 COUNT 1 STREAMS mystream >

# Processing fails -- explicitly release the message back to pending
XNACK mystream mygroup <message-id>

# The message stays pending and can be claimed by another consumer
XAUTOCLAIM mystream mygroup consumer2 0 0-0

What improvements did Redis 8.8 bring to search, JSON, and time series commands?

Redis 8.8 delivers targeted quality-of-life improvements across the search, JSON, and time series modules that reduce the number of commands and round-trips required for common analytical patterns.

  • FT.HYBRID KNN shard candidates: You can now pass a per-shard candidate count to FT.HYBRID, giving you a performance knob to trade recall for latency on large clusters. Pair this with FT.PROFILE HYBRID (also new) to measure the impact before tuning production.
  • Multiple aggregators per TS.RANGE call: Time series range queries now accept more than one aggregator in a single command (TS.RANGE, TS.REVRANGE, TS.MRANGE, TS.MREVRANGE). In practice this eliminates the pattern of issuing N separate range commands to compute avg, min, and max over the same window.
  • JSON.SET FPHA argument: Specify the floating-point representation for homogeneous FP arrays. This is important if you store ML embeddings or sensor readings and care about wire-format precision and memory layout consistency.
  • COUNT aggregator for set operations: ZUNION, ZINTER, ZUNIONSTORE, and ZINTERSTORE now support a COUNT aggregator in addition to the existing SUM, MIN, and MAX options.
# Multiple aggregators in a single time series range call
TS.MRANGE - + AGGREGATION avg 60000 AGGREGATION max 60000 FILTER sensor=temp

# Sorted set union with COUNT aggregation
ZUNION 2 zset1 zset2 AGGREGATE COUNT WITHSCORES

How do field-level hash notifications change event-driven architectures on Redis 8.8?

Redis 8.8 introduces subkey notifications for hash fields, allowing clients to subscribe to keyspace or keyevent notifications scoped to individual hash fields rather than only the top-level key.

In a typical event-driven design backed by Redis hashes -- think session objects, user profiles, or feature flag maps -- a field update previously fired a notification on the entire hash key. Any subscriber had to fetch the whole hash and diff it to find what changed. With field-level notifications, a subscriber can react precisely to changes in, for example, user:42 -> status without pulling unrelated fields or doing client-side diffing. This matters if you have high-cardinality hashes and many downstream consumers that only care about a subset of fields.

# Enable keyspace notifications including hash field subkey events
# In redis.conf or via CONFIG SET:
CONFIG SET notify-keyspace-events "Khx"

# Subscribe to field-level events on a specific hash
PSUBSCRIBE __keyevent@0__:hset:user:42:status

Frequently Asked Questions about Redis 8.8

Is Redis 8.8 a direct upgrade from Redis 8.6 or does it skip 8.7?
Redis 8.8 is the GA release that follows 8.6 as the stable branch; 8.7 was not released as a stable version, so you upgrade from 8.6 directly to 8.8 and the release notes compare changes against 8.6.

What is the INCREX command syntax in Redis 8.8 GA versus the release candidate?
The syntax was changed between RC1 and the GA release (tracked in pull request 15237). You should always reference the final GA documentation when using INCREX, as the RC syntax is not compatible. The basic form is INCREX key increment MAX|MIN bound EX seconds.

Does the new Array data structure persist to RDB and AOF like other Redis types?
Yes, the Array type is a native Redis data structure and participates in the standard persistence mechanisms, including RDB snapshots and AOF logging, just like Strings, Lists, and Hashes.

Can I enable memory tracking at runtime in Redis 8.8 without restarting in cluster mode?
The fix shipped in 8.8 GA enables runtime toggling of memory tracking only in non-clustered mode. If you are running a Redis Cluster, you still need to set the option at startup through the configuration file.

How does FT.PROFILE HYBRID help with diagnosing vector search performance in Redis 8.8?
FT.PROFILE HYBRID exposes per-shard candidate counts and timing breakdowns for hybrid KNN queries, so you can see whether latency is coming from the vector search phase or the full-text filter phase, and then tune the new KNN shard candidate argument accordingly.

Does the RedisBloom memory leak fix in 8.8 require a full RDB reload or is it transparent?
The fix (RedisBloom pull request 1007, MOD-15418) resolves a leak that occurred during RDB load, so upgrading to 8.8 GA prevents the leak from occurring on future restarts without requiring any manual intervention to existing data files.

Releases In Branch 8.8

VersionRelease date
8.8.123 Jul 2026
(15 days ago)
8.8.025 May 2026
(2 months ago)
8.8-rc114 May 2026
(2 months ago)