Manage Key Expiration with TTL
Learn to set and manage key expiration in Redis using TTL. This lesson covers the core concept, step-by-step usage, practical exercises, and troubleshooting for automatic key expiry.
Focus: manage key expiration with ttl
Have you ever stored data in Redis only to find it lingering long after it's useful — bloating memory and slowing down reads? Without expiration, every key lives forever, turning your cache into a landfill. That's where TTL (Time To Live) comes in: a built-in mechanism that automatically evicts keys after a specified duration, keeping your dataset lean and your application fast.
The problem this lesson solves
Imagine you're building a session store for a social app. Every user login creates a session key. Over a week, you accumulate millions of stale sessions. Without expiration, Redis memory balloons, eviction policies kick in (often evicting useful keys), and performance degrades. Worse, manual cleanup is error-prone and doesn't scale.
TTL solves this by giving every key a self-destruct timer. Once the timer hits zero, the key vanishes automatically. This lesson teaches you how to set, inspect, and manage those timers using Redis commands — ensuring your cache stays fresh and your memory stays under control.
Core concept / mental model
Think of TTL as a countdown timer attached to each Redis key. The clock ticks down in seconds. When it reaches zero, the key is evicted (the data is removed forever).
SET key value EX 60— set a key that expires in 60 seconds.TTL key— check how many seconds remain.EXPIRE key 30— attach a timer to an existing key.PERSIST key— remove the timer, making the key permanent.
Pro tip: Redis doesn't guarantee immediate deletion at TTL=0. It uses lazy eviction (removed on access) and active eviction (a background process samples keys). But for most apps, the difference is microseconds.
Key terminology
| Term | Definition |
|---|---|
| TTL | Time To Live — remaining seconds until expiration. |
| EXPIRE | Command to set TTL on an existing key. |
| PERSIST | Command to remove TTL. |
| Expiry | The absolute timestamp when the key will be evicted. |
How it works step by step
- Set a key with expiration during creation using
SETwith theEXorPXoption. - Check remaining TTL with
TTL— returns-2if key doesn't exist,-1if no expiration is set. - Modify expiration on an existing key using
EXPIRE,EXPIREAT(Unix timestamp), orPERSISTto remove it. - Handle timeout — your application must treat a missing key (returned as
nil) as an expiration event.
What happens at expiration?
- Memory — the key is removed, and its memory is reclaimed for new data.
- Blocks — if the key was blocking (e.g., a list used with
BLPOP), expiration causes the command to returnnil. - Subscribers — if using keyspace notifications, a
expiredevent can be published.
Hands-on walkthrough
Let's put TTL to work. Open your Redis CLI and try these examples.
Example 1: Set a key with 10-second TTL
SET session:abc123 "user:42" EX 10
# Output: OK
# Check remaining time
TTL session:abc123
# Output: (integer) 8 (varies by moment)
# Wait 10 seconds, then try to get it
GET session:abc123
# Output: (nil)
Example 2: Attach expiration to an existing key
SET mykey "hello"
# Output: OK
EXPIRE mykey 30
# Output: (integer) 1 (success)
TTL mykey
# Output: (integer) 28
Example 3: Remove expiration (make permanent)
PERSIST mykey
# Output: (integer) 1 (removed)
TTL mykey
# Output: (integer) -1 (no expiration)
Example 4: Use Unix timestamp for precise expiry
# Expire at midnight 2026-01-01 UTC (1767225600 Unix)
EXPIREAT mykey 1767225600
# Output: (integer) 1
Compare options / when to choose what
| Approach | Pros | Cons | Best for |
|---|---|---|---|
SET key value EX N |
Atomic, clean | Cannot adjust if you need different TTL later | One-shot cache entries |
EXPIRE key N |
Flexible, after creation | More round trips | Sessions with dynamic TTL |
EXPIREAT key timestamp |
Absolute control | Requires time management | Daily/epoch-based expiry |
PERSIST key |
Removes TTL | Reverses timer | Keep a key alive after expiration |
Pro tip: Use
SET key value EX NoverSET + EXPIREwhen possible. It's atomic and reduces network calls.
Troubleshooting & edge cases
Common mistakes
- Setting TTL after
INCRorLPUSH— those commands don't acceptEX. You must callEXPIREexplicitly. - Using
TTLon a key that doesn't exist — returns-2, not an error. Check for-2in logic. - Confusing
-1(no expiry) with-2(no key) — always validate which state your code expects. - Forgetting that
EXPIREwith 0 or negative removes the key instantly —EXPIRE key 0acts likeDEL.
Edge cases
- SLAVE / replica — expiration is replicated, but replicas don't execute active expiry themselves; they rely on master.
- Large keys — evicting a 1 MB string creates memory fragmentation; use careful sizing.
- Expiry on non-string types (hashes, sets) — works identically; the whole key expires, not individual fields.
What you learned & what's next
You now know how to manage key expiration with TTL in Redis: setting, inspecting, modifying, and removing timers. You can keep your cache lean and automatically purge stale data.
Next lesson: [Redis Pub/Sub — publish/subscribe messaging] — where you'll learn how to broadcast messages to many subscribers without polling.
Practice recap
Try this: Write a Python script that uses redis-py to set a key with SET mykey 'temp' EX 5, then loop until TTL mykey becomes -2 (prints -1 if no expiry or -2 if gone). Observe how Redis evicts the key. Then extend it to handle the case where the key doesn't exist after expiration.
Common mistakes
- Using
EXPIREon a key that doesn't exist — returns 0 (failure), but no error is raised, leading to silent bugs. - Setting TTL via
INCRorLPUSH— these commands don't acceptEX. You must callEXPIREseparately. - Treating
TTL -1and-2the same —-1means no expiry,-2means key missing. Check both in your application logic. - Forgetting that expiration on a non-string type (e.g., hash) evicts the entire key, not a single field.
Variations
- Use
SETEXas a shorthand forSET key value EX N—SETEX key N valuedoes the same in one command. - Use
PEXPIREfor millisecond precision instead of seconds:PEXPIRE key 5000expires after 5 seconds. - Use
PERSISTto remove expiration from a key that had a TTL, making it permanent again.
Real-world use cases
- Cache session tokens for 30 minutes after login to limit memory usage and force re-authentication.
- Rate-limit API endpoints by setting a key with
INCRandEXPIRE— reset every 60 seconds. - Store temporary one-time codes (e.g., email verification) with a 5-minute TTL to auto-invalidate.
Key takeaways
- TTL automatically evicts keys when the countdown reaches zero, keeping Redis memory lean.
- Use
SET key value EX Nfor atomic creation with expiration. EXPIREadds TTL to an existing key;PERSISTremoves it.- Check
TTLreturn values:-1(no expiry) vs-2(no key) — handle both in code. - Expiration works on all data types (strings, hashes, lists) — the whole key expires.
- For absolute time control, use
EXPIREATwith a Unix timestamp.
Keep learning
Related tutorials, quizzes, and articles for this topic.
Discussion
Questions, corrections, and tips help everyone reading this page.
0 comments
Add a comment
No comments yet — start the thread.