Redis Keyspace Notifications Setup Prompt
Configure notify-keyspace-events to receive expired, evicted, and mutation events via keyspace/keyevent pub/sub, with delivery caveats.
- Target user
- Engineers reacting to key changes and expirations
- Difficulty
- Intermediate
- Tools
- Claude, ChatGPT
The prompt
You are a senior Redis engineer who has wired keyspace notifications into event-driven systems and knows their delivery limits. I will provide: - What events I want to react to (expiry, eviction, specific commands) - My Redis topology (standalone, replica, Cluster) - How my consumers subscribe Your job: 1. **Enable notifications**: `CONFIG SET notify-keyspace-events` with a flag string. Explain each flag: K (keyspace channel), E (keyevent channel), g (generic DEL/EXPIRE/RENAME), $ (string), l (list), s (set), h (hash), z (zset), x (expired), e (evicted), t (stream), m (key-miss), A (alias for g$lshzxet — NOT including m). You MUST include K and/or E or nothing is published. 2. **Choose channel form**: keyspace channel `__keyspace@<db>__:<key>` carries the event name; keyevent channel `__keyevent@<db>__:<event>` carries the key name. Pick based on whether you subscribe by key or by event. 3. **Subscribe correctly**: use PSUBSCRIBE with patterns, e.g. `__keyevent@0__:expired`. Note the DB index in the channel. 4. **Understand the expiry caveat**: the `expired` event fires when a key is actually removed (lazy on access OR by the active expiry cycle), NOT precisely at TTL zero — expect delay for keys never accessed. 5. **Understand delivery guarantees**: pub/sub is fire-and-forget. If no subscriber is connected, events are lost. There is no replay — use Streams if you need durability. 6. **Replica behavior**: historically expired events were only generated on the master; verify your version. Evicted events depend on maxmemory-policy. 7. **Cost awareness**: enabling A on a busy instance generates high notification volume — enable only the flags you consume. 8. **Cluster**: notifications are node-local; subscribe on the node owning the keys or use keyspace across all nodes. Mark DESTRUCTIVE: CONFIG SET without persisting via CONFIG REWRITE (lost on restart), enabling firehose flags on a hot instance, FLUSHALL in tests. --- Events wanted: [DESCRIBE] Topology: [DESCRIBE] Consumer subscription: [DESCRIBE]
Why this prompt works
Keyspace notifications are commonly wired up wrong: the flag string is cryptic, events silently do not fire without K or E, and teams assume durable delivery from a fire-and-forget pub/sub. This prompt makes the model decode the flags, pick the right channel form, and confront the expiry-timing and delivery caveats before you build logic that depends on catching every event.
How to use it
- List exactly which events you need (expired? evicted? a specific command?).
- State your topology — standalone vs replica vs Cluster changes behavior.
- Describe how consumers subscribe so channel/DB indexes line up.
- Ask whether Streams is a better fit if you need durability.
Useful commands
# Enable: keyevent channel + expired + evicted events
redis-cli CONFIG SET notify-keyspace-events "Exe"
redis-cli CONFIG GET notify-keyspace-events
redis-cli CONFIG REWRITE # persist to redis.conf
# Subscribe to all expiry events on DB 0
redis-cli PSUBSCRIBE '__keyevent@0__:expired'
# Subscribe to all events on a specific key (keyspace form needs K flag)
redis-cli CONFIG SET notify-keyspace-events "KEA"
redis-cli PSUBSCRIBE '__keyspace@0__:cart:42'
# Test it
redis-cli SET cart:42 x PX 2000 # expect an 'expired' event ~2s later
Example config
# redis.conf: enable expired + evicted keyevent notifications only
notify-keyspace-events "Exe"
# Flag reference:
# K = keyspace channel (__keyspace@db__:key)
# E = keyevent channel (__keyevent@db__:event)
# x = expired events, e = evicted events, g = generic (DEL/EXPIRE/RENAME)
# $ l s h z t = per-type, A = g$lshzxet alias (NOT m/key-miss)
#
# For DURABLE eventing prefer Streams instead:
# XADD events:expired '*' key cart:42 reason ttl
# XREADGROUP GROUP workers c1 COUNT 10 STREAMS events:expired '>'
Common findings this catches
- No K/E flag → notifications enabled but nothing publishes.
- Wrong DB index → subscriber gets silence.
- Expected exact-TTL timing → delayed expired events.
- Assumed durability → events lost when consumer down.
- Firehose A on hot instance → notification storm and CPU cost.
- Not persisted → config lost after restart.
- Cluster single subscriber → misses other nodes’ events.
When to escalate
- Requirement for exactly-once/durable events — move to Redis Streams.
- Cluster-wide reliable eventing — architecture review.
- High-volume notification load impacting latency — capacity planning.
Related prompts
-
Redis Pub/Sub Messaging Design Prompt
Design Redis messaging — Pub/Sub vs Streams, fan-out patterns, sharded pub/sub, and the at-most-once delivery caveats to plan around.
-
Redis Streams Consumer Groups Design Prompt
Design Redis Streams processing — XADD/XREADGROUP/XACK, pending entries lists, claiming stuck messages, and trimming for at-least-once delivery.
-
Redis TTL and Expiration Strategy Prompt
Design TTL hygiene with EXPIRE/PEXPIRE, understand active vs lazy expiry, and avoid immortal keys and expiry-driven latency spikes.