{"id":26123,"date":"2022-06-24T12:02:18","date_gmt":"2022-06-24T02:02:18","guid":{"rendered":"https:\/\/database.guide\/?p=26123"},"modified":"2022-06-27T11:57:59","modified_gmt":"2022-06-27T01:57:59","slug":"redis-expireat-command-explained","status":"publish","type":"post","link":"https:\/\/database.guide\/redis-expireat-command-explained\/","title":{"rendered":"Redis EXPIREAT Command Explained"},"content":{"rendered":"\n<p>The Redis <code>EXPIREAT<\/code> command sets a timeout as a Unix timestamp on a given key. It works the same as the <code><a href=\"https:\/\/database.guide\/redis-expire-command-explained\/\" data-type=\"post\" data-id=\"26111\">EXPIRE<\/a><\/code> command, but with an absolute Unix timestamp instead of a time interval in seconds (which <code>EXPIRE<\/code> uses).<\/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>EXPIREAT key unix-time-seconds &#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-seconds<\/em><\/code><\/td><td>The absolute Unix timestamp of the timeout.<\/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\/expireat\/\" data-type=\"URL\" data-id=\"https:\/\/redis.io\/commands\/expireat\/\" 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 dinner \"Pizza\"<\/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>TTL<\/code> command against it:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>TTL dinner<\/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>EXPIREAT<\/code> to set an expiry:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>EXPIREAT dinner 1656182885<\/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 1656182885. 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>TTL dinner<\/code><\/pre>\n\n\n\n<p>Result:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">(integer) 398851<\/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-expiretime-command-explained\/\" data-type=\"post\" data-id=\"26130\">EXPIRETIME<\/a><\/code> to check the absolute Unix timestamp of the expiry:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>EXPIRETIME dinner<\/code><\/pre>\n\n\n\n<p>Result:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">(integer) 1656182885<\/pre>\n\n\n\n<p>So it&#8217;s exactly as we specified. <\/p>\n\n\n\n<p>Note that the <code>EXPIRETIME<\/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>EXPIREAT dinner 1656182880 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 dinner<\/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>EXPIREAT dinner 1656182880 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. In case you&#8217;re wondering, all I did was change the last digit from <code>5<\/code> to <code>0<\/code>.<\/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>TTL dinner<\/code><\/pre>\n\n\n\n<p>Result:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">(integer) 398700<\/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>EXPIREAT dinner 1656182800 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>Looks like it worked. In this case I changed the second last digit from <code>8<\/code> to <code>0<\/code>.<\/p>\n\n\n\n<p>Let&#8217;s check the current TTL:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>TTL dinner<\/code><\/pre>\n\n\n\n<p>Result:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">(integer) 398529<\/pre>\n\n\n\n<p>Looks good.<\/p>\n\n\n\n<p>Let&#8217;s also use the <code>EXPIRETIME<\/code> command to check the absolute Unix time of the expiry:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>EXPIRETIME dinner<\/code><\/pre>\n\n\n\n<p>Result:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">(integer) 1656182800<\/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>To test this, let&#8217;s try updating our key with a smaller timeout:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>EXPIREAT dinner 1656182000 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 smaller 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>EXPIREAT dinner 1656182880 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>EXPIREAT dinner 1656182885 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 larger 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>EXPIREAT dinner 1656182800 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 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).<\/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-26123","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\/26123","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=26123"}],"version-history":[{"count":5,"href":"https:\/\/database.guide\/wp-json\/wp\/v2\/posts\/26123\/revisions"}],"predecessor-version":[{"id":26229,"href":"https:\/\/database.guide\/wp-json\/wp\/v2\/posts\/26123\/revisions\/26229"}],"wp:attachment":[{"href":"https:\/\/database.guide\/wp-json\/wp\/v2\/media?parent=26123"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/database.guide\/wp-json\/wp\/v2\/categories?post=26123"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/database.guide\/wp-json\/wp\/v2\/tags?post=26123"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}