Redis PEXPIRE Command Explained

The Redis PEXPIRE command sets a timeout on a given key in milliseconds. After the timeout has expired, the key will be deleted.

The PEXPIRE command works exactly the same as the EXPIRE command, except that it returns the timeout in milliseconds instead of seconds.

Syntax

The syntax goes like this:

PEXPIRE key milliseconds [ NX | XX | GT | LT]

Explanation of arguments:

keyThe key for which to set the timeout.
millisecondsThe number of milliseconds for 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.

Example

Suppose we set a key:

SET breakfast "Muesli"

Result:

OK

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

PTTL breakfast

Result:

(integer) -1

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

The PTTL command returns a key’s time to live in milliseconds. We can alternatively use the TTL command to return the time to live in seconds.

Now let’s use PEXPIRE to set an expiry:

PEXPIRE breakfast 86400000

Result:

(integer) 1

We got an integer reply of 1, which means it was successful.

Let’s check its time to live:

PTTL breakfast

Result:

(integer) 86351862

We still have plenty of time left before it expires.

We can also use the PEXPIRETIME command to get the absolute Unix time of its expiry.

PEXPIRETIME breakfast

Result:

(integer) 1655978136926

The EXPIRETIME command does the same thing, but returns the result in seconds.

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:

PEXPIRE breakfast 100000000 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 breakfast

Result:

(integer) 1

And try again:

PEXPIRE breakfast 100000000 NX

Result:

(integer) 1

This time we were successful.

Let’s check the time to live:

PTTL breakfast

Result:

(integer) 99988589

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:

PEXPIRE breakfast 500000000 XX

Result:

(integer) 1

Looks like it worked.

Let’s use PTTL to check the current time to live:

PTTL breakfast

Result:

(integer) 499969158

Looks good.

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:

PEXPIRE breakfast 400000000 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:

PEXPIRE breakfast 500000000 GT

Result:

(integer) 1

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

Note that my new expiry is the same as the 500000000 that I had previously used to set the timeout. However, time has elapsed since then, and the time to live has therefore decreased. Therefore, my new value happens to be higher than the current time to live.

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:

PEXPIRE breakfast 600000000 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:

PEXPIRE breakfast 400000000 LT

Result:

(integer) 1

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