Skip to content
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
105 changes: 105 additions & 0 deletions content/develop/pubsub/subkeyspace-notifications.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
---
categories:
- docs
- develop
- stack
- oss
- rs
- rc
- oss
- kubernetes
- clients
description: Monitor changes to individual hash fields in real time
Comment thread
dwdougherty marked this conversation as resolved.
Outdated
linkTitle: Sub-keyspace notifications
title: Redis sub-keyspace notifications
weight: 5
---

Sub-keyspace notifications, added in Redis 8.8, extend Redis's existing [keyspace notification]({{< relref "/develop/pubsub/keyspace-notifications" >}}) system to include **field-level** (subkey) details for hash operations.

Comment thread
dwdougherty marked this conversation as resolved.
With standard keyspace notifications, when a hash field is modified via [`HSET`]({{< relref "/commands/hset" >}}), [`HDEL`]({{< relref "/commands/hdel" >}}), or [`HEXPIRE`]({{< relref "/commands/hexpire" >}}), the subscriber receives the key name and the event type but not which specific fields were affected. Sub-keyspace notifications solve this by carrying the affected field names in the message payload.

Sub-keyspace notifications are delivered through Pub/Sub channels and are independent of the standard keyspace/keyevent notification channels. Enabling sub-keyspace notifications does **not** implicitly enable standard keyspace notifications, and vice versa.

Note: Redis Pub/Sub is *fire and forget*. If your Pub/Sub client disconnects and reconnects later, all events delivered during the disconnection period are lost.

### Notification channels

Four new channel types are available, each suited to a different subscription pattern:

| Channel format | Payload |
|---|---|
| `__subkeyspace@<db>__:<key>` | `<event>\|<len>:<subkey>[,...]` |
| `__subkeyevent@<db>__:<event>` | `<key_len>:<key>\|<len>:<subkey>[,...]` |
| `__subkeyspaceitem@<db>__:<key>\n<subkey>` | `<event>` |
| `__subkeyspaceevent@<db>__:<event>\|<key>` | `<len>:<subkey>[,...]` |

**Design rationale:**

- **Subkeyspace** (`__subkeyspace@<db>__:<key>`): Subscribe to a specific key and receive all field changes in a single message. Efficient for key-centric consumers.
Comment thread
dwdougherty marked this conversation as resolved.
Outdated
- **Subkeyevent** (`__subkeyevent@<db>__:<event>`): Subscribe to a specific event type and receive the key and affected fields. Efficient for event-centric consumers.
Comment thread
dwdougherty marked this conversation as resolved.
Outdated
- **Subkeyspaceitem** (`__subkeyspaceitem@<db>__:<key>\n<subkey>`): Subscribe to a specific key+field combination. The most selective option — one message per field, no payload parsing required.
Comment thread
dwdougherty marked this conversation as resolved.
Outdated
- **Subkeyspaceevent** (`__subkeyspaceevent@<db>__:<event>|<key>`): Subscribe to an event+key combination and receive only the affected fields. Provides server-side filtering on both dimensions.
Comment thread
dwdougherty marked this conversation as resolved.
Outdated

Subkeys in the payload are encoded in a length-prefixed format (`<len>:<subkey>`) to support binary-safe field names that may contain delimiter characters.

**Safety guards:**
Comment thread
dwdougherty marked this conversation as resolved.
Outdated

- Events whose name contains `|` are skipped for the `__subkeyspace` and `__subkeyspaceevent` channels to avoid parsing ambiguity.
- Keys containing `\n` are skipped for the `__subkeyspaceitem` channel because newline is the key/subkey separator.
- Sub-keyspace events are only published when at least one subkey (field) is present.

### Configuration

Sub-keyspace notifications are controlled via the existing `notify-keyspace-events` configuration string. Four new flag characters are added:

S Subkeyspace events, published with __subkeyspace@<db>__ prefix.
T Subkeyevent events, published with __subkeyevent@<db>__ prefix.
I Subkeyspaceitem events, published with __subkeyspaceitem@<db>__ prefix.
V Subkeyspaceevent events, published with __subkeyspaceevent@<db>__ prefix.
Comment thread
dwdougherty marked this conversation as resolved.

These flags are **independent** from the existing key-level flags (`K`, `E`, and so on). You may enable any combination. For example, to enable only the subkeyspace and subkeyevent channels:

$ redis-cli config set notify-keyspace-events ST
Comment thread
dwdougherty marked this conversation as resolved.

To enable all four sub-keyspace channel types:

$ redis-cli config set notify-keyspace-events STIV

### Events generated by hash commands

The following hash operations emit sub-keyspace notifications that include the names of the affected fields:

| Command | Event | Subkeys (fields) included |
|---|---|---|
| [`HSET`]({{< relref "/commands/hset" >}}) / [`HMSET`]({{< relref "/commands/hmset" >}}) | `hset` | All fields being set |
| [`HSETNX`]({{< relref "/commands/hsetnx" >}}) | `hset` | The field (only if it was set) |
| [`HDEL`]({{< relref "/commands/hdel" >}}) | `hdel` | All fields deleted |
| [`HGETDEL`]({{< relref "/commands/hgetdel" >}}) | `hdel` / `hexpired` | Deleted or lazily expired fields |
| [`HGETEX`]({{< relref "/commands/hgetex" >}}) | `hexpire` / `hpersist` / `hdel` / `hexpired` | Affected fields per event type |
| [`HINCRBY`]({{< relref "/commands/hincrby" >}}) | `hincrby` | The field |
| [`HINCRBYFLOAT`]({{< relref "/commands/hincrbyfloat" >}}) | `hincrbyfloat` | The field |
| [`HEXPIRE`]({{< relref "/commands/hexpire" >}}) / [`HPEXPIRE`]({{< relref "/commands/hpexpire" >}}) / [`HEXPIREAT`]({{< relref "/commands/hexpireat" >}}) / [`HPEXPIREAT`]({{< relref "/commands/hpexpireat" >}}) | `hexpire` | Fields whose TTL was updated |
Comment thread
dwdougherty marked this conversation as resolved.
Outdated
| [`HPERSIST`]({{< relref "/commands/hpersist" >}}) | `hpersist` | Fields that were persisted |
| [`HSETEX`]({{< relref "/commands/hsetex" >}}) | `hset` / `hdel` / `hexpire` / `hexpired` | Affected fields per event type |
| Field expiration (active or lazy) | `hexpired` | All expired fields, batched into a single notification |

For field expiration, expired fields are collected and sent as a single batched notification after the expiration cycle completes, rather than one notification per field.
Comment thread
dwdougherty marked this conversation as resolved.
Outdated

### Watching events in real time

To observe sub-keyspace notifications, enable the desired channel types and use `redis-cli` to subscribe with a glob pattern:

$ redis-cli config set notify-keyspace-events ST
$ redis-cli --csv psubscribe '__subkey*'
Reading messages... (press Ctrl-C to quit)
"psubscribe","__subkey*",1

Then, in another terminal, run a hash command:

$ redis-cli hset myhash field1 val1 field2 val2

You will see messages similar to the following:

"pmessage","__subkey*","__subkeyspace@0__:myhash","hset|7:field1,7:field2"
"pmessage","__subkey*","__subkeyevent@0__:hset","5:myhash|7:field1,7:field2"
Loading