Redis EXPIRE then PERSIST Behavior

301 views
Skip to first unread message

Tom Jin

unread,
Jun 8, 2017, 11:34:45 PM6/8/17
to Redis DB
We would like some clarification on the EXPIRE then PERSIST behavior in Redis. 

We've noticed that if you EXPIRE a key, wait until the key expires, then run the PERSIST command, the key will actually still be persisted. However, if you EXPIRE a key, wait until the key expires, then run a GET command before running the PERSIST command, the key will no longer exist. This is illustrated with the two examples below.

According to the documentation, "The timeout can also be cleared, turning the key back into a persistent key, using the PERSIST command.". Does this essentially mean that the timeout can be cleared regardless of whether the key is expired or not? 

Thanks!

127.0.0.1:6179> SET "mykey" "hello"

OK

127.0.0.1:6179> GET "mykey"

"hello"

127.0.0.1:6179> EXPIRE "mykey" 2

(integer) 1

[Wait for more than 2 seconds...]

127.0.0.1:6179> PERSIST "mykey"

(integer) 1

127.0.0.1:6179> GET "mykey"

"hello"




127.0.0.1:6179> SET "mykey" "hello"

OK

127.0.0.1:6179> GET "mykey"

"hello"

127.0.0.1:6179> EXPIRE "mykey" 2

(integer) 1

[Wait for more than 2 seconds...]

127.0.0.1:6179> GET "mykey"

(nil)

127.0.0.1:6179> PERSIST "mykey"

(integer) 0

hva...@gmail.com

unread,
Jun 9, 2017, 7:51:50 AM6/9/17
to Redis DB

You're thinking that an expired key is deleted from the Redis database at the instant it expires, so the different behavior of PERSIST before a GET, and PERSIST after a GET, doesn't make any sense.  But that's not what happens in Redis, because deleting thousands of keys that expire at the same time would produce large spikes in cpu consumption and make Redis slow.  This would happen unpredictably over time, with no recourse by the user except to avoid using EXPIRE or TTL on keys.

To avoid these problems, Redis does not necessarily delete a key the instant it expires. Instead, Redis treats the key in a way that's similar to how most operating systems treat a deleted file.  The file is marked unavailable, but for a time afterward, it can be "undeleted" because the file's data structures have not been removed or re-used.  Redis runs a background thread that goes through the database gradually finding and deleting expired keys, so eventually the key will disappear.  The cpu usage by the background thread is quite small and steady, nothing like the spikes I described above.

The PERSIST command is like a file "undelete".  But you have to invoke PERSIST before the key is deleted by the background thread or by other activity. One activity that can force an expired key to be deleted is to try to read it with GET (or similar commands).  The reason is, the GET command operates on just one key, and the cpu overhead in deleting the key is insignificant.  Redis has the opportunity to delete the key and free the memory it was using (the most common reason for expiration), so Redis does it.

PERSIST wasn't really intended to be used on keys after they expire, though.  It was intended to be used on keys that haven't expired yet.

The behavior on expired-but-not deleted keys is unexpected, but not the normal use case.  You could probably make a case for this being a bug because it's inconsistent with other commands like GET.  I can see the possibility of a race condition or other situation where the PERSIST command should not cause an expired key to be deleted, so it might not actually be a bug.

Itamar Haber

unread,
Jun 9, 2017, 10:08:31 AM6/9/17
to Redis DB
That's a great and accurate write up hvarzan - IMO it is a bug with an apparent easy fix :) Lazy expiration does not mean that keys can be revived post their TTL so just like GET, PERSIST should honor that.

Tom - I suggest that you open an issue in the project's repository (https://github.com/antirez/redis/issues) with the above details so it may be addressed in a future version.

--
You received this message because you are subscribed to the Google Groups "Redis DB" group.
To unsubscribe from this group and stop receiving emails from it, send an email to redis-db+unsubscribe@googlegroups.com.
To post to this group, send email to redi...@googlegroups.com.
Visit this group at https://groups.google.com/group/redis-db.
For more options, visit https://groups.google.com/d/optout.



--

Itamar Haber | Chief OSS Education Officer
Redis Labs ~/redis

Mobile: +972 (54) 567 9692
Twitter: @itamarhaber
Skype: itamar.haber

Tom Jin

unread,
Jun 10, 2017, 3:50:06 PM6/10/17
to Redis DB
Thanks for the great responses hvarzan and Itamar! It makes sense how the deletion works, but I agree with Itamar that it's just a little unexpected. I've opened a tracking issue here: https://github.com/antirez/redis/issues/4048
To unsubscribe from this group and stop receiving emails from it, send an email to redis-db+u...@googlegroups.com.

To post to this group, send email to redi...@googlegroups.com.
Visit this group at https://groups.google.com/group/redis-db.
For more options, visit https://groups.google.com/d/optout.

Salvatore Sanfilippo

unread,
Jun 12, 2017, 11:32:03 AM6/12/17
to redi...@googlegroups.com
I agree, this looks like a glitch in the implementation having this
funny effect... I'll take a closer look and report back.
>> email to redis-db+u...@googlegroups.com.
>> To post to this group, send email to redi...@googlegroups.com.
>> Visit this group at https://groups.google.com/group/redis-db.
>> For more options, visit https://groups.google.com/d/optout.
>
>
>
>
> --
>
> Itamar Haber | Chief OSS Education Officer
> Redis Labs ~/redis
>
> Mobile: +972 (54) 567 9692
> Twitter: @itamarhaber
> Skype: itamar.haber
>
> --
> You received this message because you are subscribed to the Google Groups
> "Redis DB" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to redis-db+u...@googlegroups.com.
> To post to this group, send email to redi...@googlegroups.com.
> Visit this group at https://groups.google.com/group/redis-db.
> For more options, visit https://groups.google.com/d/optout.



--
Salvatore 'antirez' Sanfilippo
open source developer - Redis Labs https://redislabs.com

"If a system is to have conceptual integrity, someone must control the
concepts."
— Fred Brooks, "The Mythical Man-Month", 1975.

kamarapu Shivachandra

unread,
Sep 22, 2022, 8:09:06 AMSep 22
to Redis DB
inshort :
redis expires works the following way ->
redis says "i will delete the key when someone asks for the key whose TTL is reached "
hence after TTL is reached and you asked for that key -> it showed nil
but when u said persist -> it like no one is asking for the key -> we are just making changes in the property of the key 

this is my undestanding 
Reply all
Reply to author
Forward
0 new messages