In-Memory Key-Value Store with TTL

mediumPython

Lesson

Time-Based Data Expiration in Memory

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.

How TTL Works

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.

Cleanup Strategies

There are two main approaches to handling expired data:

  1. Active cleanup: Use background processes or timers to periodically scan and remove expired items
  2. Lazy cleanup: Check expiration when data is accessed and remove expired items on-the-fly

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.

Real-World Applications

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.

Example
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
L4Each cache entry stores both the value and its expiration timestamp
L7Calculate expiration time by adding TTL to current timestamp
L13Compare current time with expiration to determine if data is still valid
L14Lazy cleanup: remove expired data when it's accessed

Key Takeaways

  • •TTL systems store data with expiration timestamps, calculated as current_time + ttl_duration
  • •Lazy cleanup checks expiration during access and removes stale data automatically
  • •This pattern prevents memory leaks and ensures temporary data doesn't persist indefinitely
Loading...