100% Free Forever
AI-Powered Learning
Industry Expert Content
Certificates & Badges
Learn At Your Own Pace
Redis

Key Expiration and TTL

Learn how Redis lets keys expire automatically using TTLs, and how expiration is implemented internally through lazy and active mechanisms.

Key ManagementBeginner9 min readJul 10, 2026
Analogies

What Is a TTL?

A Time To Live (TTL) is a countdown, in seconds or milliseconds, that Redis attaches to a key. Once the TTL reaches zero, Redis treats the key as if it never existed, even though the data structure and memory may not be reclaimed the exact instant the countdown hits zero. TTLs are the primary mechanism for building caches, session stores, rate limiters, and temporary locks in Redis, because they let you say 'store this, but forget it automatically' without writing any cleanup code yourself.

🏏

Cricket analogy: A TTL is like the 90-second injury assessment window a physio gets on the field for Rishabh Pant after a blow to the helmet — once the clock runs out, the umpire's decision to continue or retire the batter happens automatically, no manual reminder needed.

Setting and Inspecting TTLs

You can attach a TTL when writing a key using SET key value EX seconds (or PX for milliseconds), or apply one afterward with EXPIRE key seconds, PEXPIRE key milliseconds, EXPIREAT key unix-timestamp, or PEXPIREAT for millisecond-precision absolute timestamps. To check remaining lifetime, use TTL key (seconds) or PTTL key (milliseconds); both return -1 if the key exists but has no expiration set, and -2 if the key does not exist at all. Removing an expiration entirely, so the key becomes permanent again, is done with PERSIST key.

🏏

Cricket analogy: Setting EXPIREAT is like the ICC scheduling a rain-delay cutoff time for a T20 match at exactly 11:00 PM local time — it's an absolute deadline, not a countdown from now, just as EXPIREAT takes a Unix timestamp rather than a relative duration.

bash
# Set a key with a 60-second TTL at write time
SET session:user:42 "active" EX 60

# Check remaining time to live
TTL session:user:42
(integer) 60

# Apply an expiration to an existing key
SET cache:homepage "<html>..." 
EXPIRE cache:homepage 300

# Set an absolute expiration timestamp (Unix epoch seconds)
EXPIREAT promo:code:SUMMER25 1752192000

# Remove the expiration, making the key permanent again
PERSIST cache:homepage

# PTTL for millisecond precision
PTTL session:user:42
(integer) 58213

How Redis Actually Expires Keys

Redis does not run a dedicated timer thread per key; instead it uses two complementary strategies. Lazy (passive) expiration checks a key's TTL the moment it's accessed by any command — if it's expired, Redis deletes it on the spot and reports a miss, as if it had never existed. Active expiration runs a background cycle roughly 10 times per second, in which Redis randomly samples a small batch of keys with TTLs set, deletes any that have expired, and repeats the sampling if more than 25% of the sample was expired, so that infrequently accessed expired keys don't sit around forever consuming memory.

🏏

Cricket analogy: Lazy expiration is like a scorer only checking whether a batter has already been given out when the next ball is about to be bowled, rather than watching continuously; active expiration is like the third umpire periodically reviewing random deliveries even without an appeal.

Because active expiration samples keys randomly rather than scanning everything, a key with a TTL can briefly continue consuming memory after its logical expiration time, especially under high key-space cardinality. If you need guaranteed prompt cleanup for memory-sensitive workloads, consider combining TTLs with Redis keyspace notifications or monitoring INFO memory rather than assuming instantaneous reclamation.

Replication and Persistence Behavior

In a primary-replica setup, replicas do not independently expire keys; instead the primary detects expiration (lazily or actively) and propagates an explicit DEL (or UNLINK) command to replicas, so all nodes agree on when a key disappeared. This avoids clock-drift inconsistencies between servers. On RDB snapshot reload or AOF replay, Redis checks each key's stored expiration timestamp against the current time and skips loading any key whose TTL has already passed, so expired data doesn't come back to life after a restart.

🏏

Cricket analogy: This is like the on-field umpire, not the third umpire, making the final call on a run-out and radioing it to the scorers' box, so every scoreboard around the ground updates in sync rather than each one guessing independently.

OBJECT FREQ, DEBUG JMAP, and RDB timestamp fields aside, the practical takeaway is simple: TTLs are primary-driven and propagate as explicit deletions, and RDB/AOF reload always re-validates expiration against wall-clock time before restoring a key. Never assume a restarted Redis instance will resurrect data past its TTL.

  • TTLs can be set at write time (SET ... EX/PX) or after the fact (EXPIRE, PEXPIRE, EXPIREAT, PEXPIREAT).
  • TTL and PTTL report remaining lifetime in seconds/milliseconds; -1 means no TTL, -2 means the key doesn't exist.
  • PERSIST removes a key's expiration, making it permanent again.
  • Redis combines lazy expiration (checked on access) with active expiration (a background sampling cycle ~10 times/second).
  • Active expiration re-samples if more than 25% of the sampled batch was expired, to keep memory pressure low.
  • Primaries propagate expiration as an explicit DEL/UNLINK to replicas so the whole cluster agrees on timing.
  • RDB and AOF reloads re-check expiration timestamps against current time, so expired keys never come back after a restart.

Practice what you learned

Was this page helpful?

Topics covered

#Redis#RedisStudyNotes#Database#KeyExpirationAndTTL#Key#Expiration#TTL#Setting#StudyNotes#SkillVeris