Learnitweb

Redis Key Expiration Notifications Tutorial

In earlier lessons, we explored basic Redis operations — setting key-value pairs, incrementing and decrementing values, and even extending the lifetime of a key.
However, we haven’t yet discussed one important aspect: how to get notified when a key expires in Redis.

This tutorial focuses on exactly that — listening for Redis key expiration events using a simple event listener.


1. Why Do We Need Expiration Notifications?

Redis allows you to set a time-to-live (TTL) for keys. Once the TTL expires, the key is automatically deleted.
But in many real-world applications, you might want to react to such expirations — for example:

  • Invalidation of a user session when its token expires.
  • Performing cleanup actions after cached data is removed.
  • Notifying other services when a temporary key is deleted.

By default, Redis deletes the expired key silently — no event is published unless you explicitly enable notifications.
We’ll learn how to enable this and listen to expiration events.


2. Understanding Redis Event Listeners

Redis supports keyspace notifications — special events that can be published when keys are created, modified, or expired.
To handle such events, you can write an event listener that subscribes to Redis channels corresponding to those events.

In Java, if you are using Redisson, you can easily register such listeners.

Here’s the idea:

  • You create a listener that extends ExpiredObjectListener.
  • You override the method that gets triggered when a key expires.
  • Redis will pass the expired key name as the parameter.
  • You can then take appropriate actions (like logging or cleanup).

3. Example Code for Key Expiration Listener

Let’s walk through an example where we create a Redis key that expires in 10 seconds and listen for its expiration event.

import org.redisson.api.RBucket;
import org.redisson.api.RKeys;
import org.redisson.api.RedissonClient;
import org.redisson.api.listener.ExpiredObjectListener;

public class KeyExpirationExample {

    public static void main(String[] args) throws InterruptedException {
        RedissonClient redisson = RedissonConfig.getClient();

        // Create a bucket (key) with a TTL of 10 seconds
        RBucket<String> bucket = redisson.getBucket("user:1:name");
        bucket.set("John", 10, TimeUnit.SECONDS);
        System.out.println("Key created with TTL = 10 seconds");

        // Add a listener for expired keys
        redisson.getKeys().getKeys().addListener(new ExpiredObjectListener() {
            @Override
            public void onExpired(String expiredKey) {
                System.out.println("Expired Key: " + expiredKey);
            }
        });

        // Sleep long enough for the key to expire
        Thread.sleep(11000);

        System.out.println("End of program.");
    }
}

What’s Happening Here

  1. We create a Redis key user:1:name and set it to expire after 10 seconds.
  2. We register a listener implementing ExpiredObjectListener.
  3. When Redis deletes the key due to expiration, the listener’s onExpired() method is invoked.
  4. We sleep for 11 seconds to ensure the key expires before the program ends.

4. Why You Might Not See Any Notifications Initially

If you run the above code and see no output for the expired event, don’t worry — Redis does not emit keyspace notifications by default.

You must explicitly enable notification settings before Redis will publish such events.


5. Enabling Redis Keyspace Notifications

Redis provides a configuration parameter called notify-keyspace-events that controls which events should be published.
By default, this is empty, meaning no events are emitted.

You can enable it in two ways:

Option 1: Temporary (Runtime) Configuration

Use the CONFIG SET command in Redis CLI:

CONFIG SET notify-keyspace-events Ex
  • E stands for Keyevent notifications.
  • x stands for Expired events.

Alternatively, to listen to all kinds of keyspace events (except missing-key lookups), use:

CONFIG SET notify-keyspace-events AKE

This will enable:

  • All event types (A)
  • Keyspace notifications (K)
  • Expired events (E)

Note: This change is temporary — it resets when Redis restarts.


Option 2: Permanent (Configuration File)

Edit your Redis configuration file (redis.conf) and set:

notify-keyspace-events Ex

Then restart Redis.
This ensures the configuration persists across reboots — ideal for production setups.


6. Verifying That Notifications Work

After enabling notifications, rerun your Java code.
When the key expires, you should see output like:

Key created with TTL = 10 seconds
Expired Key: user:1:name
End of program.

This confirms that Redis is now notifying your application of key expirations.


7. Understanding Event Types and Options

The notify-keyspace-events setting accepts a combination of flags representing different types of notifications.
Here’s what they mean:

FlagMeaning
KKeyspace events, published with the prefix __keyspace@<db>__
EKeyevent events, published with the prefix __keyevent@<db>__
AAlias for all event types except m
gGeneric commands (like DEL, RENAME)
xExpired events
eEvicted events (due to memory policy)
mKey-miss events (when accessing missing keys)

For most cases, Ex or AKE is enough.


8. Behavior in Distributed Environments

If you have multiple microservices or multiple instances of your Java application connected to the same Redis instance, every listener will be notified when the key expires.

This can be useful for:

  • Coordinating cache invalidations across nodes.
  • Broadcasting session expirations to all services.
  • Triggering asynchronous cleanup tasks in a distributed system.

Each client can decide whether or not to act on the notification.


9. Summary

  • Redis supports keyspace notifications for events like key creation, modification, expiration, and deletion.
  • These notifications are disabled by default and must be enabled using notify-keyspace-events.
  • You can use Redisson’s ExpiredObjectListener interface to listen for expiration events.
  • When a key expires, Redis sends the key name to all registered listeners.
  • This mechanism is powerful in distributed systems where multiple clients depend on shared cache states.