The Problem

You've configured Redis keyspace notifications expecting your application to receive events when keys expire or change, but nothing arrives. The subscription seems active, commands execute successfully, yet your event handlers never fire. This silent failure pattern is common when the notification configuration doesn't match the event types being monitored.

Diagnosing the Issue

First, verify that keyspace notifications are enabled at all. Redis disables them by default for performance reasons:

bash
redis-cli CONFIG GET notify-keyspace-events

If the response shows an empty string or just "", notifications are disabled. You need to enable specific event types.

Check what event characters mean:

bash
K     Keyspace events, published with __keyspace@<db>__ prefix
E     Keyevent events, published with __keyevent@<db>__ prefix
g     Generic commands (DEL, EXPIRE, RENAME, ...)
$     String commands
l     List commands
s     Set commands
h     Hash commands
z     Sorted set commands
x     Expired events (events generated every time a key expires)
e     Evicted events (events generated when a key is evicted for maxmemory)
A     Alias for g$lshzxe, so "AKE" means all events

Common Misconfigurations

Missing Event Type Flags

The most common issue: enabling only keyspace or keyevent notifications but not the specific command types. For example:

```bash # This enables keyspace events but NO command types - nothing fires redis-cli CONFIG SET notify-keyspace-events "K"

# Correct - enables keyspace events AND string commands redis-cli CONFIG SET notify-keyspace-events "K$" ```

Expired Events Without Expiry Flag

A frequent mistake when monitoring key expiration:

```bash # This won't capture expirations redis-cli CONFIG SET notify-keyspace-events "KE"

# This will capture expirations redis-cli CONFIG SET notify-keyspace-events "KEx" ```

Database Mismatch

Subscriptions are database-specific. If your application subscribes to database 0 but writes to database 1:

```bash # Check which database your client is using redis-cli CLIENT LIST | grep -i db

# Subscribe to all databases with pattern PSUBSCRIBE __key*__:*keyname* ```

Step-by-Step Resolution

Step 1: Verify Current Configuration

bash
redis-cli CONFIG GET notify-keyspace-events

Step 2: Enable Appropriate Notifications

For most use cases including expiration events:

bash
redis-cli CONFIG SET notify-keyspace-events "AKE"

For production with only expiration monitoring:

bash
redis-cli CONFIG SET notify-keyspace-events "Ex"

Step 3: Make Configuration Persistent

Add to your redis.conf:

bash
notify-keyspace-events "AKE"

Step 4: Test the Notification

Open two terminal sessions. In terminal 1:

bash
redis-cli PSUBSCRIBE "__keyevent@0__:expired"

In terminal 2:

bash
redis-cli SET testkey "value" EX 2

Wait 2 seconds and check terminal 1 - you should see:

bash
1) "pmessage"
2) "__keyevent@0__:expired"
3) "__keyevent@0__:expired"
4) "testkey"

Verifying With INFO

Check notification statistics:

bash
redis-cli INFO stats | grep -i notify

Look for expired_keys to confirm keys are expiring.

Client Library Considerations

Different Redis clients handle pub/sub differently. With Node.js ioredis:

```javascript const Redis = require('ioredis'); const subscriber = new Redis();

subscriber.psubscribe('__keyevent@0__:expired', (err, count) => { if (err) console.error('Subscription error:', err); });

subscriber.on('pmessage', (pattern, channel, message) => { console.log(Key expired: ${message}); }); ```

Ensure you're using a separate connection for subscriptions - blocked connections cannot issue other commands.

Performance Impact

Keyspace notifications add CPU overhead for event generation. In high-throughput scenarios:

bash
# Monitor CPU impact
redis-cli --latency-history

If latency increases significantly after enabling notifications, consider:

  1. 1.Subscribing to fewer event types
  2. 2.Using a dedicated notification server
  3. 3.Implementing polling instead for non-critical events