{"id":26154,"date":"2022-06-24T12:02:14","date_gmt":"2022-06-24T02:02:14","guid":{"rendered":"https:\/\/database.guide\/?p=26154"},"modified":"2022-06-27T11:58:08","modified_gmt":"2022-06-27T01:58:08","slug":"redis-pexpireat-command-explained","status":"publish","type":"post","link":"https:\/\/database.guide\/redis-pexpireat-command-explained\/","title":{"rendered":"Redis PEXPIREAT Command Explained"},"content":{"rendered":"\n<p>The Redis <code>PEXPIREAT<\/code> command sets a timeout as a Unix timestamp on a given key in milliseconds. It works the same as the <code><a href=\"https:\/\/database.guide\/redis-expireat-command-explained\/\" data-type=\"post\" data-id=\"26123\">EXPIREAT<\/a><\/code> command, except that it sets the timeout in milliseconds instead of seconds.<\/p>\n\n\n\n<p>It&#8217;s also similar to the <code><a href=\"https:\/\/database.guide\/redis-pexpire-command-explained\/\" data-type=\"post\" data-id=\"26152\">PEXPIRE<\/a><\/code> command, but with an absolute Unix timestamp instead of a time interval.<\/p>\n\n\n\n<!--more-->\n\n\n\n<h2 class=\"wp-block-heading\">Syntax<\/h2>\n\n\n\n<p>The syntax goes like this:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>PEXPIREAT key unix-time-milliseconds &#91; NX | XX | GT | LT]<\/code><\/pre>\n\n\n\n<p>Explanation of arguments:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table><tbody><tr><td><code><em>key<\/em><\/code><\/td><td>The key for which to set the timeout.<\/td><\/tr><tr><td><code><em>unix-time-milliseconds<\/em><\/code><\/td><td>The absolute Unix timestamp of the timeout in milliseconds.<\/td><\/tr><tr><td><code>NX<\/code><\/td><td>Sets an expiry only when the key has no expiry.<\/td><\/tr><tr><td><code>XX<\/code><\/td><td>Sets an expiry only when the key has an existing expiry.<\/td><\/tr><tr><td><code>GT<\/code><\/td><td>Sets an expiry only when the new expiry is greater than current one.<\/td><\/tr><tr><td><code>LT<\/code><\/td><td>Sets an expiry only when the new expiry is less than current one.<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p>The <code>NX<\/code>, <code>XX<\/code>, <code>GT<\/code>, and <code>LT<\/code> arguments were introduced in Redis 7.0.0.<\/p>\n\n\n\n<p>See the <a href=\"https:\/\/redis.io\/commands\/pexpireat\/\" data-type=\"URL\" data-id=\"https:\/\/redis.io\/commands\/pexpireat\/\" target=\"_blank\" rel=\"noreferrer noopener\">Redis documentation<\/a> for any changes since this article was written.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Example<\/h2>\n\n\n\n<p>Suppose we set a key:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>SET beverage \"Coffee\"<\/code><\/pre>\n\n\n\n<p>Result:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">OK<\/pre>\n\n\n\n<p>We didn&#8217;t set an expiry for this key, so when I run the <code><a href=\"https:\/\/database.guide\/redis-pttl-command-explained\/\" data-type=\"post\" data-id=\"26158\">PTTL<\/a><\/code> command against it:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>PTTL beverage<\/code><\/pre>\n\n\n\n<p>Result:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">(integer) -1<\/pre>\n\n\n\n<p>We get an integer reply of <code>-1<\/code> (which means it has no expiry).<\/p>\n\n\n\n<p>Now let&#8217;s use <code>PEXPIREAT<\/code> to set an expiry:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>PEXPIREAT beverage 1656040209088<\/code><\/pre>\n\n\n\n<p>Result:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">(integer) 1<\/pre>\n\n\n\n<p>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&#8217;ll need to do so before that Unix time (unless I change the timeout to a different value).<\/p>\n\n\n\n<p>Let&#8217;s check its time to live:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>PTTL beverage<\/code><\/pre>\n\n\n\n<p>Result:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">(integer) 86290741<\/pre>\n\n\n\n<p>So we still have plenty of time left.<\/p>\n\n\n\n<p>We can also use the <code><a href=\"https:\/\/database.guide\/redis-pexpiretime-command-explained\/\" data-type=\"post\" data-id=\"26137\">PEXPIRETIME<\/a><\/code> to check the absolute Unix timestamp of the expiry:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>PEXPIRETIME beverage<\/code><\/pre>\n\n\n\n<p>Result:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">(integer) 1656040209088<\/pre>\n\n\n\n<p>So it&#8217;s exactly as we specified. <\/p>\n\n\n\n<p>Note that the <code>PEXPIRETIME<\/code> command was introduced in 7.0.0.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">The <code>NX<\/code> Argument<\/h2>\n\n\n\n<p>The <code>NX<\/code> argument was introduced in Redis 7.0.0. <\/p>\n\n\n\n<p>We can use the <code>NX<\/code> argument to set the timeout only if the key doesn&#8217;t already have an expiry. <\/p>\n\n\n\n<p>To demonstrate this, let&#8217;s first try to set the expiry on the key that we used in the previous example:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>PEXPIREAT beverage 1656040209080 NX<\/code><\/pre>\n\n\n\n<p>Result:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">(integer) 0<\/pre>\n\n\n\n<p>It doesn&#8217;t work. We get an integer reply of <code>0<\/code>, which means that the timeout wasn&#8217;t set.<\/p>\n\n\n\n<p>Let&#8217;s remove the expiry:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>PERSIST beverage<\/code><\/pre>\n\n\n\n<p>Result:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">(integer) 1<\/pre>\n\n\n\n<p>And try again:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>PEXPIREAT beverage 1656040209080 NX<\/code><\/pre>\n\n\n\n<p>Result:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">(integer) 1<\/pre>\n\n\n\n<p>This time we were successful.<\/p>\n\n\n\n<p>Let&#8217;s check the time to live:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>PTTL beverage<\/code><\/pre>\n\n\n\n<p>Result:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">(integer) 84844859<\/pre>\n\n\n\n<p>Yes, it worked as expected.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">The <code>XX<\/code> Argument<\/h2>\n\n\n\n<p>The <code>XX<\/code> argument was introduced in Redis 7.0.0. <\/p>\n\n\n\n<p>We can use the <code>XX<\/code> argument to set the timeout only if the key already has an expiry.<\/p>\n\n\n\n<p>Let&#8217;s try updating the same key from the previous examples:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>PEXPIREAT beverage 1656040209000 XX<\/code><\/pre>\n\n\n\n<p>Result:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">(integer) 1<\/pre>\n\n\n\n<p>It worked.<\/p>\n\n\n\n<p>Let&#8217;s check the current TTL:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>PTTL beverage<\/code><\/pre>\n\n\n\n<p>Result:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">(integer) 84774111<\/pre>\n\n\n\n<p>Looks good. That&#8217;s how many milliseconds to go until the key expires.<\/p>\n\n\n\n<p>Let&#8217;s also use the <code>PEXPIRETIME<\/code> command to check the absolute Unix time of the expiry:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>PEXPIRETIME beverage<\/code><\/pre>\n\n\n\n<p>Result:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">(integer) 1656040209000<\/pre>\n\n\n\n<p>Yes, it&#8217;s exactly as we specified.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">The <code>GT<\/code> Argument<\/h2>\n\n\n\n<p>The <code>GT<\/code> argument was introduced in Redis 7.0.0. <\/p>\n\n\n\n<p>We can use the <code>GT<\/code> argument to set the timeout only if the new expiry is greater than current one.<\/p>\n\n\n\n<p>First, let&#8217;s try updating our key with a smaller timeout:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>PEXPIREAT beverage 1656040200000 GT<\/code><\/pre>\n\n\n\n<p>Result:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">(integer) 0<\/pre>\n\n\n\n<p>It didn&#8217;t work, because the new expiry is less than the current one.<\/p>\n\n\n\n<p>Let&#8217;s try again, with a larger expiry:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>PEXPIREAT beverage 1656040210000 GT<\/code><\/pre>\n\n\n\n<p>Result:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">(integer) 1<\/pre>\n\n\n\n<p>This time it worked, because our expiry is greater than the current one.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">The <code>LT<\/code> Argument<\/h2>\n\n\n\n<p>The <code>LT<\/code> argument was introduced in Redis 7.0.0. <\/p>\n\n\n\n<p>We can use the <code>LT<\/code> argument to set the timeout only if the new expiry is less than current one.<\/p>\n\n\n\n<p>To test this, let&#8217;s try updating our key with a larger timeout:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>PEXPIREAT beverage 1656040219000 LT<\/code><\/pre>\n\n\n\n<p>Result:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">(integer) 0<\/pre>\n\n\n\n<p>It didn&#8217;t work, because the new expiry is greater than the current one.<\/p>\n\n\n\n<p>Let&#8217;s try again, with a smaller expiry:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>PEXPIREAT beverage 1656040200000 LT<\/code><\/pre>\n\n\n\n<p>Result:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">(integer) 1<\/pre>\n\n\n\n<p>This time it worked, because our expiry is less than the current one.<\/p>\n\n\n\n<p>Note that non-volatile keys (i.e. keys with no expiry) are considered infinite for the purpose of the <code>LT<\/code> and <code>GT<\/code> arguments.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>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&#8217;s also similar to the PEXPIRE command, but with an absolute Unix timestamp instead of a time interval.<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[153],"tags":[154,20],"class_list":["post-26154","post","type-post","status-publish","format-standard","hentry","category-redis","tag-commands","tag-what-is"],"_links":{"self":[{"href":"https:\/\/database.guide\/wp-json\/wp\/v2\/posts\/26154","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/database.guide\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/database.guide\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/database.guide\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/database.guide\/wp-json\/wp\/v2\/comments?post=26154"}],"version-history":[{"count":5,"href":"https:\/\/database.guide\/wp-json\/wp\/v2\/posts\/26154\/revisions"}],"predecessor-version":[{"id":26261,"href":"https:\/\/database.guide\/wp-json\/wp\/v2\/posts\/26154\/revisions\/26261"}],"wp:attachment":[{"href":"https:\/\/database.guide\/wp-json\/wp\/v2\/media?parent=26154"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/database.guide\/wp-json\/wp\/v2\/categories?post=26154"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/database.guide\/wp-json\/wp\/v2\/tags?post=26154"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}