When building applications, you often need to store temporary data that should automatically disappear after a certain time. This pattern is called Time-To-Live (TTL) and is fundamental to caching systems, session management, and temporary data storage.
The core challenge is tracking both the data and when it should expire. Unlike simple dictionaries that only store key-value pairs, TTL systems must store three pieces of information: the key, the value, and the expiration timestamp.
When you store data with a TTL, you calculate an expiration timestamp by adding the TTL duration to the current time. For example, if the current time is 1000 seconds and you set a TTL of 300 seconds, the expiration timestamp becomes 1300 seconds.
When retrieving data, you compare the current time with the stored expiration timestamp. If the current time has passed the expiration time, the data is considered expired and should be treated as if it doesn't exist.
There are two main approaches to handling expired data:
Lazy cleanup is simpler to implement and works well for moderate data volumes. It ensures expired data is eventually removed without requiring complex timer management.
TTL is everywhere in software systems. Web sessions expire after inactivity, DNS records have TTL values to control caching duration, and Redis (a popular caching database) uses TTL extensively. Authentication tokens often have expiration times to limit security exposure.
The pattern is so useful because it provides automatic memory management for temporary data, preventing systems from accumulating stale information that could cause memory leaks or incorrect behavior.
1import time
2
3class SimpleCache:
4 def __init__(self):
5 # Store items as (value, expiration_time) tuples
6 self.cache = {}
7
8 def put(self, key, value, ttl_seconds):
9 expiration = time.time() + ttl_seconds
10 self.cache[key] = (value, expiration)
11
12 def get(self, key):
13 if key not in self.cache:
14 return None
15
16 value, expiration = self.cache[key]
17 if time.time() >= expiration:
18 del self.cache[key] # Lazy cleanup
19 return None
20
21 return value
22
23# Usage example
24cache = SimpleCache()
25cache.put("user_session", "abc123", 30) # Expires in 30 seconds
26print(cache.get("user_session")) # Returns "abc123"
27# After 30+ seconds, returns None