Redis PEXPIREAT Command Explained

The Redis PEXPIREAT command sets a timeout as a Unix timestamp on a given key in milliseconds. It works the same as the EXPIREAT command, except that it sets the timeout in milliseconds instead of seconds.

It’s also similar to the PEXPIRE command, but with an absolute Unix timestamp instead of a time interval.

Syntax

The syntax goes like this:

PEXPIREAT key unix-time-milliseconds [ NX | XX | GT | LT]

Explanation of arguments:

keyThe key for which to set the timeout.
unix-time-millisecondsThe absolute Unix timestamp of the timeout in milliseconds.
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 beverage "Coffee"

Result:

OK

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

PTTL beverage

Result:

(integer) -1

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

Now let’s use PEXPIREAT to set an expiry:

PEXPIREAT beverage 1656040209088

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 1656040209088 (in milliseconds). 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:

PTTL beverage

Result:

(integer) 86290741

So we still have plenty of time left.

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

PEXPIRETIME beverage

Result:

(integer) 1656040209088

So it’s exactly as we specified.

Note that the PEXPIRETIME 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:

PEXPIREAT beverage 1656040209080 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 beverage

Result:

(integer) 1

And try again:

PEXPIREAT beverage 1656040209080 NX

Result:

(integer) 1

This time we were successful.

Let’s check the time to live:

PTTL beverage

Result:

(integer) 84844859

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:

PEXPIREAT beverage 1656040209000 XX

Result:

(integer) 1

It worked.

Let’s check the current TTL:

PTTL beverage

Result:

(integer) 84774111

Looks good. That’s how many milliseconds to go until the key expires.

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

PEXPIRETIME beverage

Result:

(integer) 1656040209000

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.

First, let’s try updating our key with a smaller timeout:

PEXPIREAT beverage 1656040200000 GT

Result:

(integer) 0

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

Let’s try again, with a larger expiry:

PEXPIREAT beverage 1656040210000 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:

PEXPIREAT beverage 1656040219000 LT

Result:

(integer) 0

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

Let’s try again, with a smaller expiry:

PEXPIREAT beverage 1656040200000 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.