Redis EXPIREAT Command Explained

The Redis EXPIREAT command sets a timeout as a Unix timestamp on a given key. It works the same as the EXPIRE command, but with an absolute Unix timestamp instead of a time interval in seconds (which EXPIRE uses).

Syntax

The syntax goes like this:

EXPIREAT key unix-time-seconds [ NX | XX | GT | LT]

Explanation of arguments:

keyThe key for which to set the timeout.
unix-time-secondsThe absolute Unix timestamp of the timeout.
NXSets an expiry only when the key has no expiry.
XXSets an expiry only when the key has an existing expiry.
GTSets an expiry only when the new expiry is greater than current one.
LTSets an expiry only when the new expiry is less than current one.

The NX, XX, GT, and LT arguments were introduced in Redis 7.0.0.

See the Redis documentation for any changes since this article was written.

Example

Suppose we set a key:

SET dinner "Pizza"

Result:

OK

We didn’t set an expiry for this key, so when I run the TTL command against it:

TTL dinner

Result:

(integer) -1

We get an integer reply of -1 (which means it has no expiry).

Now let’s use EXPIREAT to set an expiry:

EXPIREAT dinner 1656182885

Result:

(integer) 1

I got an integer reply of 1, which means it was successful. Here, I set the expiry to an absolute Unix time of 1656182885. This means that if I want to use the key, I’ll need to do so before that Unix time (unless I change the timeout to a different value).

Let’s check its time to live:

TTL dinner

Result:

(integer) 398851

So we still have plenty of time left.

We can also use the EXPIRETIME to check the absolute Unix timestamp of the expiry:

EXPIRETIME dinner

Result:

(integer) 1656182885

So it’s exactly as we specified.

Note that the EXPIRETIME command was introduced in 7.0.0.

The NX Argument

The NX argument was introduced in Redis 7.0.0.

We can use the NX argument to set the timeout only if the key doesn’t already have an expiry.

To demonstrate this, let’s first try to set the expiry on the key that we used in the previous example:

EXPIREAT dinner 1656182880 NX

Result:

(integer) 0

It doesn’t work. We get an integer reply of 0, which means that the timeout wasn’t set.

Let’s remove the expiry:

PERSIST dinner

Result:

(integer) 1

And try again:

EXPIREAT dinner 1656182880 NX

Result:

(integer) 1

This time we were successful. In case you’re wondering, all I did was change the last digit from 5 to 0.

Let’s check the time to live:

TTL dinner

Result:

(integer) 398700

Yes, it worked as expected.

The XX Argument

The XX argument was introduced in Redis 7.0.0.

We can use the XX argument to set the timeout only if the key already has an expiry.

Let’s try updating the same key from the previous examples:

EXPIREAT dinner 1656182800 XX

Result:

(integer) 1

Looks like it worked. In this case I changed the second last digit from 8 to 0.

Let’s check the current TTL:

TTL dinner

Result:

(integer) 398529

Looks good.

Let’s also use the EXPIRETIME command to check the absolute Unix time of the expiry:

EXPIRETIME dinner

Result:

(integer) 1656182800

Yes, it’s exactly as we specified.

The GT Argument

The GT argument was introduced in Redis 7.0.0.

We can use the GT argument to set the timeout only if the new expiry is greater than current one.

To test this, let’s try updating our key with a smaller timeout:

EXPIREAT dinner 1656182000 GT

Result:

(integer) 0

It didn’t work, because the new expiry is smaller than the current one.

Let’s try again, with a larger expiry:

EXPIREAT dinner 1656182880 GT

Result:

(integer) 1

This time it worked, because our expiry is greater than the current one.

The LT Argument

The LT argument was introduced in Redis 7.0.0.

We can use the LT argument to set the timeout only if the new expiry is less than current one.

To test this, let’s try updating our key with a larger timeout:

EXPIREAT dinner 1656182885 LT

Result:

(integer) 0

It didn’t work, because the new expiry is larger than the current one.

Let’s try again, with a smaller expiry:

EXPIREAT dinner 1656182800 LT

Result:

(integer) 1

This time it worked, because our expiry is less than the current one.

Note that non-volatile keys (i.e. keys with no expiry) are considered infinite for the purpose of the LT and GT arguments.