EXPIRE (2024)

Syntax

EXPIRE key seconds [NX | XX | GT | LT]
Available since:
1.0.0
Time complexity:
O(1)
ACL categories:
@keyspace, @write, @fast,

Set a timeout on key.After the timeout has expired, the key will automatically be deleted.A key with an associated timeout is often said to be volatile in Redisterminology.

The timeout will only be cleared by commands that delete or overwrite thecontents of the key, including DEL, SET, GETSET and all the *STOREcommands.This means that all the operations that conceptually alter the value stored atthe key without replacing it with a new one will leave the timeout untouched.For instance, incrementing the value of a key with INCR, pushing a new valueinto a list with LPUSH, or altering the field value of a hash with HSET areall operations that will leave the timeout untouched.

The timeout can also be cleared, turning the key back into a persistent key,using the PERSIST command.

If a key is renamed with RENAME, the associated time to live is transferred tothe new key name.

If a key is overwritten by RENAME, like in the case of an existing key Key_Athat is overwritten by a call like RENAME Key_B Key_A, it does not matter ifthe original Key_A had a timeout associated or not, the new key Key_A willinherit all the characteristics of Key_B.

Note that calling EXPIRE/PEXPIRE with a non-positive timeout orEXPIREAT/PEXPIREAT with a time in the past will result in the key beingdeleted rather than expired (accordingly, the emitted key eventwill be del, not expired).

Options

The EXPIRE command supports a set of options:

  • NX -- Set expiry only when the key has no expiry
  • XX -- Set expiry only when the key has an existing expiry
  • GT -- Set expiry only when the new expiry is greater than current one
  • LT -- Set expiry only when the new expiry is less than current one

A non-volatile key is treated as an infinite TTL for the purpose of GT and LT.The GT, LT and NX options are mutually exclusive.

Refreshing expires

It is possible to call EXPIRE using as argument a key that already has anexisting expire set.In this case the time to live of a key is updated to the new value.There are many useful applications for this, an example is documented in theNavigation session pattern section below.

Differences in Redis prior 2.1.3

In Redis versions prior 2.1.3 altering a key with an expire set using acommand altering its value had the effect of removing the key entirely.This semantics was needed because of limitations in the replication layer thatare now fixed.

EXPIRE would return 0 and not alter the timeout for a key with a timeout set.

Examples

> SET mykey "Hello""OK"> EXPIRE mykey 10(integer) 1> TTL mykey(integer) 10> SET mykey "Hello World""OK"> TTL mykey(integer) -1> EXPIRE mykey 10 XX(integer) 0> TTL mykey(integer) -1> EXPIRE mykey 10 NX(integer) 1> TTL mykey(integer) 10

Are you tired of using redis-cli? Try Redis Insight - the developer GUI for Redis.

import redisr = redis.Redis(decode_responses=True)res = r.set("key1", "Hello")print(res)# >>> Trueres = r.set("key2", "World")print(res)# >>> Trueres = r.delete("key1", "key2", "key3")print(res)# >>> 2res = r.set("mykey", "Hello")print(res)# >>> Trueres = r.expire("mykey", 10)print(res)# >>> Trueres = r.ttl("mykey")print(res)# >>> 10res = r.set("mykey", "Hello World")print(res)# >>> Trueres = r.ttl("mykey")print(res)# >>> -1res = r.expire("mykey", 10, xx=True)print(res)# >>> Falseres = r.ttl("mykey")print(res)# >>> -1res = r.expire("mykey", 10, nx=True)print(res)# >>> Trueres = r.ttl("mykey")print(res)# >>> 10res = r.set("mykey", "Hello")print(res)# >>> Trueres = r.expire("mykey", 10)print(res)# >>> Trueres = r.ttl("mykey")print(res)# >>> 10res = r.sadd("myset", *set([1, 2, 3, "foo", "foobar", "feelsgood"]))print(res)# >>> 6res = list(r.sscan_iter("myset", match="f*"))print(res)# >>> ['foobar', 'foo', 'feelsgood']cursor, key = r.scan(cursor=0, match='*11*')print(cursor, key)cursor, key = r.scan(cursor, match='*11*')print(cursor, key)cursor, key = r.scan(cursor, match='*11*')print(cursor, key)cursor, key = r.scan(cursor, match='*11*')print(cursor, key)cursor, keys = r.scan(cursor, match='*11*', count=1000)print(cursor, keys)res = r.geoadd("geokey", (0, 0, "value"))print(res)# >>> 1res = r.zadd("zkey", {"value": 1000})print(res)# >>> 1res = r.type("geokey")print(res)# >>> zsetres = r.type("zkey")print(res)# >>> zsetcursor, keys = r.scan(cursor=0, _type="zset")print(keys)# >>> ['zkey', 'geokey']res = r.hset("myhash", mapping={"a": 1, "b": 2})print(res)# >>> 2cursor, keys = r.hscan("myhash", 0)print(keys)# >>> {'a': '1', 'b': '2'}cursor, keys = r.hscan("myhash", 0, no_values=True)print(keys)# >>> ['a', 'b']

using NRedisStack.Tests;using StackExchange.Redis;public class CmdsGenericExample{ [SkipIfRedis(Is.OSSCluster, Comparison.LessThan, "7.0.0")] public void run() { var muxer = ConnectionMultiplexer.Connect("localhost:6379"); var db = muxer.GetDatabase(); // Tests for 'copy' step. bool delResult1 = db.StringSet("key1", "Hello"); Console.WriteLine(delResult1); // >>> true bool delResult2 = db.StringSet("key2", "World"); Console.WriteLine(delResult2); // >>> true long delResult3 = db.KeyDelete(new RedisKey[] { "key1", "key2", "key3" }); Console.WriteLine(delResult3); // >>> 2 // Tests for 'del' step. // Tests for 'dump' step. // Tests for 'exists' step. bool expireResult1 = db.StringSet("mykey", "Hello"); Console.WriteLine(expireResult1); // >>> true bool expireResult2 = db.KeyExpire("mykey", new TimeSpan(0, 0, 10)); Console.WriteLine(expireResult2); // >>> true TimeSpan expireResult3 = db.KeyTimeToLive("mykey") ?? TimeSpan.Zero; Console.WriteLine(Math.Round(expireResult3.TotalSeconds)); // >>> 10 bool expireResult4 = db.StringSet("mykey", "Hello World"); Console.WriteLine(expireResult4); // >>> true TimeSpan expireResult5 = db.KeyTimeToLive("mykey") ?? TimeSpan.Zero; Console.WriteLine(Math.Round(expireResult5.TotalSeconds).ToString()); // >>> 0 bool expireResult6 = db.KeyExpire("mykey", new TimeSpan(0, 0, 10), ExpireWhen.HasExpiry); Console.WriteLine(expireResult6); // >>> false TimeSpan expireResult7 = db.KeyTimeToLive("mykey") ?? TimeSpan.Zero; Console.WriteLine(Math.Round(expireResult7.TotalSeconds)); // >>> 0 bool expireResult8 = db.KeyExpire("mykey", new TimeSpan(0, 0, 10), ExpireWhen.HasNoExpiry); Console.WriteLine(expireResult8); // >>> true TimeSpan expireResult9 = db.KeyTimeToLive("mykey") ?? TimeSpan.Zero; Console.WriteLine(Math.Round(expireResult9.TotalSeconds)); // >>> 10 // Tests for 'expire' step. // Tests for 'expireat' step. // Tests for 'expiretime' step. // Tests for 'keys' step. // Tests for 'migrate' step. // Tests for 'move' step. // Tests for 'object_encoding' step. // Tests for 'object_freq' step. // Tests for 'object_idletime' step. // Tests for 'object_refcount' step. // Tests for 'persist' step. // Tests for 'pexpire' step. // Tests for 'pexpireat' step. // Tests for 'pexpiretime' step. // Tests for 'pttl' step. // Tests for 'randomkey' step. // Tests for 'rename' step. // Tests for 'renamenx' step. // Tests for 'restore' step. // Tests for 'scan1' step. // Tests for 'scan2' step. // Tests for 'scan3' step. // Tests for 'scan4' step. // Tests for 'sort' step. // Tests for 'sort_ro' step. // Tests for 'touch' step. bool ttlResult1 = db.StringSet("mykey", "Hello"); Console.WriteLine(ttlResult1); // >>> true bool ttlResult2 = db.KeyExpire("mykey", new TimeSpan(0, 0, 10)); Console.WriteLine(ttlResult2); TimeSpan ttlResult3 = db.KeyTimeToLive("mykey") ?? TimeSpan.Zero; string ttlRes = Math.Round(ttlResult3.TotalSeconds).ToString(); Console.WriteLine(Math.Round(ttlResult3.TotalSeconds)); // >>> 10 // Tests for 'ttl' step. // Tests for 'type' step. // Tests for 'unlink' step. // Tests for 'wait' step. // Tests for 'waitaof' step. }}

Give these commands a try in the interactive console:

Pattern: Navigation session

Imagine you have a web service and you are interested in the latest N pagesrecently visited by your users, such that each adjacent page view was notperformed more than 60 seconds after the previous.Conceptually you may consider this set of page views as a Navigation sessionof your user, that may contain interesting information about what kind ofproducts he or she is looking for currently, so that you can recommend relatedproducts.

You can easily model this pattern in Redis using the following strategy: everytime the user does a page view you call the following commands:

MULTIRPUSH pagewviews.user:<userid> http://.....EXPIRE pagewviews.user:<userid> 60EXEC

If the user will be idle more than 60 seconds, the key will be deleted and onlysubsequent page views that have less than 60 seconds of difference will berecorded.

This pattern is easily modified to use counters using INCR instead of listsusing RPUSH.

Appendix: Redis expires

Keys with an expire

Normally Redis keys are created without an associated time to live.The key will simply live forever, unless it is removed by the user in anexplicit way, for instance using the DEL command.

The EXPIRE family of commands is able to associate an expire to a given key,at the cost of some additional memory used by the key.When a key has an expire set, Redis will make sure to remove the key when thespecified amount of time elapsed.

The key time to live can be updated or entirely removed using the EXPIRE andPERSIST command (or other strictly related commands).

Expire accuracy

In Redis 2.4 the expire might not be pin-point accurate, and it could be betweenzero to one seconds out.

Since Redis 2.6 the expire error is from 0 to 1 milliseconds.

Expires and persistence

Keys expiring information is stored as absolute Unix timestamps (in millisecondsin case of Redis version 2.6 or greater).This means that the time is flowing even when the Redis instance is not active.

For expires to work well, the computer time must be taken stable.If you move an RDB file from two computers with a big desync in their clocks,funny things may happen (like all the keys loaded to be expired at loadingtime).

Even running instances will always check the computer clock, so for instance ifyou set a key with a time to live of 1000 seconds, and then set your computertime 2000 seconds in the future, the key will be expired immediately, instead oflasting for 1000 seconds.

How Redis expires keys

Redis keys are expired in two ways: a passive way and an active way.

A key is passively expired when a client tries to access it and thekey is timed out.

However, this is not enough as there are expired keys that will never beaccessed again.These keys should be expired anyway, so periodically, Redis tests a few keys atrandom amongst the set of keys with an expiration.All the keys that are already expired are deleted from the keyspace.

How expires are handled in the replication link and AOF file

In order to obtain a correct behavior without sacrificing consistency, when akey expires, a DEL operation is synthesized in both the AOF file and gains allthe attached replicas nodes.This way the expiration process is centralized in the master instance, and thereis no chance of consistency errors.

However while the replicas connected to a master will not expire keysindependently (but will wait for the DEL coming from the master), they'llstill take the full state of the expires existing in the dataset, so when areplica is elected to master it will be able to expire the keys independently,fully acting as a master.

RESP2/RESP3 Reply

One of the following:

  • Integer reply: 0 if the timeout was not set; for example, the key doesn't exist, or the operation was skipped because of the provided arguments.
  • Integer reply: 1 if the timeout was set.

History

  • Starting with Redis version 7.0.0: Added options: NX, XX, GT and LT.
EXPIRE (2024)
Top Articles
The 3 Most Common Business Structures - ACCES Employment
What Happens to a Bank Account When Someone Dies Without a Beneficiary?
Evil Dead Movies In Order & Timeline
Victor Spizzirri Linkedin
Wordscapes Level 6030
Air Canada bullish about its prospects as recovery gains steam
Exam With A Social Studies Section Crossword
Kobold Beast Tribe Guide and Rewards
Polyhaven Hdri
Cosentyx® 75 mg Injektionslösung in einer Fertigspritze - PatientenInfo-Service
Best Private Elementary Schools In Virginia
Gt Transfer Equivalency
litter - tłumaczenie słowa – słownik angielsko-polski Ling.pl
Oriellys St James Mn
Unit 1 Lesson 5 Practice Problems Answer Key
Aspen.sprout Forum
The fabulous trio of the Miller sisters
Tcu Jaggaer
Why Is 365 Market Troy Mi On My Bank Statement
Ruse For Crashing Family Reunions Crossword
Aldi Bruce B Downs
Isaidup
Rochester Ny Missed Connections
Rubber Ducks Akron Score
Globle Answer March 1 2023
Netwerk van %naam%, analyse van %nb_relaties% relaties
Carroway Funeral Home Obituaries Lufkin
Duke University Transcript Request
Housing Intranet Unt
Suspect may have staked out Trump's golf course for 12 hours before the apparent assassination attempt
Exploring The Whimsical World Of JellybeansBrains Only
Covalen hiring Ai Annotator - Dutch , Finnish, Japanese , Polish , Swedish in Dublin, County Dublin, Ireland | LinkedIn
Tmka-19829
Msnl Seeds
Housing Intranet Unt
Craigslist Mexicali Cars And Trucks - By Owner
Verizon Outage Cuyahoga Falls Ohio
Bartow Qpublic
Craigslist Rooms For Rent In San Fernando Valley
Random Animal Hybrid Generator Wheel
Hanco*ck County Ms Busted Newspaper
Flappy Bird Cool Math Games
844 386 9815
Learn4Good Job Posting
Www Pig11 Net
Westport gun shops close after confusion over governor's 'essential' business list
Fresno Craglist
Read Love in Orbit - Chapter 2 - Page 974 | MangaBuddy
One Facing Life Maybe Crossword
Booked On The Bayou Houma 2023
Latest Posts
Article information

Author: Duane Harber

Last Updated:

Views: 5537

Rating: 4 / 5 (51 voted)

Reviews: 82% of readers found this page helpful

Author information

Name: Duane Harber

Birthday: 1999-10-17

Address: Apt. 404 9899 Magnolia Roads, Port Royceville, ID 78186

Phone: +186911129794335

Job: Human Hospitality Planner

Hobby: Listening to music, Orienteering, Knapping, Dance, Mountain biking, Fishing, Pottery

Introduction: My name is Duane Harber, I am a modern, clever, handsome, fair, agreeable, inexpensive, beautiful person who loves writing and wants to share my knowledge and understanding with you.