Skip to content

Ask the HotKV docs

Answers come only from these docs and can be wrong; check the linked pages before you rely on them.

Keyspace notifications

Last updated

Keyspace notifications publish a Pub/Sub message whenever a key changes: a write, a delete, an expiry, an eviction. Clients subscribe to them like any other channel. Typical uses are invalidating a local cache, reacting to session expiry, or auditing changes to a set of keys during development.

Notifications are off by default, because publishing them costs CPU for every write.

Set notify-keyspace-events to a string of characters: one or both of K and E to say where events go, plus the classes of events you want.

127.0.0.1:6379> CONFIG SET notify-keyspace-events KEA
OK

or in the configuration file:

notify-keyspace-events KEA

or in hotkv.toml:

[notifications]
keyspace_events = "KEA"

An empty string turns notifications off again. Without K or E, nothing is published whatever classes you list.

Character Meaning
K Publish on the keyspace channel, __keyspace@<db>__:<key>, with the event name as the message
E Publish on the keyevent channel, __keyevent@<db>__:<event>, with the key name as the message
g Generic events: del, expire, rename_from, rename_to, persist, copy_to, move_from, move_to, restore
$ String events
l List events
s Set events
h Hash events
z Sorted set events
t Stream events
x expired: a key’s time to live ran out
e evicted: a key was evicted under maxmemory
m keymiss: a command looked up a key that does not exist
n new: a key was created
d Module key types (accepted; HotKV publishes no events in this class)
A Shorthand for g$lshztxed (every class except m and n)

Any other character makes CONFIG SET fail with an error ending in Invalid event class character. Use 'Ag$lshzxeKEtmdn'.

With KEA set, subscribe to the events you care about. A keyspace channel follows one key; a keyevent channel follows one kind of event across all keys. Use PSUBSCRIBE to cover many keys or events at once.

127.0.0.1:6379> PSUBSCRIBE __keyspace@0__:session:*
1) "psubscribe"
2) "__keyspace@0__:session:*"
3) (integer) 1

Another client runs SET session:42 token EX 60, then DEL session:42:

1) "pmessage"
2) "__keyspace@0__:session:*"
3) "__keyspace@0__:session:42"
4) "set"
1) "pmessage"
2) "__keyspace@0__:session:*"
3) "__keyspace@0__:session:42"
4) "expire"
1) "pmessage"
2) "__keyspace@0__:session:*"
3) "__keyspace@0__:session:42"
4) "del"

To hear about every expiry instead:

127.0.0.1:6379> SUBSCRIBE __keyevent@0__:expired

The event name is usually the command’s name in lower case. The ones that differ, or that a command emits in addition, are listed here.

Class Events
Generic (g) del for DEL, UNLINK, and any command that removes a key’s last element or field; expire when a TTL is set (del instead when the time has already passed); rename_from and rename_to for RENAME/RENAMENX; persist; copy_to; move_from and move_to; restore
String ($) set (for SET, SETEX, MSET, GETSET and the like), setrange, append, incrby (for INCR, DECR, INCRBY and DECRBY), incrbyfloat, setbit, pfadd
List (l) lpush, rpush, lpop, rpop, linsert, lset, lrem, ltrim, sortstore. LMOVE and BLMOVE emit a pop on the source and a push on the destination
Set (s) sadd, srem, spop, sinterstore, sunionstore, sdiffstore
Hash (h) hset, hdel, hincrby, hincrbyfloat, hexpire, hpersist, and hexpired when a field’s TTL runs out
Sorted set (z) zadd (also for GEOADD), zincr, zrem, zremrangebyscore, zremrangebyrank, zremrangebylex, zpopmin, zpopmax, zinterstore, zunionstore, zdiffstore, zrangestore
Stream (t) xadd, xdel, xtrim, xsetid, xgroup-create, xgroup-setid, xgroup-destroy, xgroup-createconsumer, xgroup-delconsumer
Expired (x) expired
Evicted (e) evicted
Key miss (m) keymiss
New key (n) new, before the event of the command that created the key

A command that changes nothing publishes nothing. For example, SADD of a member that is already there, or DEL of a missing key, emits no event. The events of a transaction or a script are published once it has finished, in the order its commands caused them.

  • Notifications are ordinary Pub/Sub messages: a client that is disconnected when an event happens never sees it. Do not use them as the only record of a change.
  • expired is published when the key is actually removed, either when a command touches it after its TTL ran out or when the background expiry sweep finds it. It can come slightly after the TTL ended, and a key nobody touches is still removed by the sweep. See Keys and expiration.
  • In a cluster, each node publishes the events for the keys it serves to its own subscribers only. Subscribe on every primary to see the whole keyspace.

The configuration string, channel names, and event names follow Redis 7. As in Redis, A does not include m or n. HotKV adds no event classes of its own, and its NEXPIRE and NEXPIREAT commands publish no expire event.