पाठ 6 / 25

TTLs, Refresh-Ahead and Negative Caching

Choose TTLs deliberately and refresh hot data before it expires.

How long should data live?

A TTL bounds staleness: after it expires, the next read reloads. Choose TTLs from business tolerance, not habit: exchange rates might accept 60 seconds, product descriptions an hour, a country list a day. Longer TTLs raise the hit ratio; shorter TTLs reduce staleness. Explicit invalidation lets you use long TTLs safely, with the TTL acting as a safety net if an invalidation is missed. Refresh-ahead reloads popular keys before they expire, in the background, so users never wait on a miss for hot data. Negative caching stores the fact that something does not exist ("no product with id 999") for a short time, so repeated lookups for missing keys do not hit the database every time; keep these TTLs short so newly created items appear quickly. Add a little random jitter to TTLs so keys created together do not all expire together.

TTL with jitter and negative caching

A sentinel value records "not found" briefly.

import json, random

NOT_FOUND = "__none__"

def ttl(base_seconds, jitter=0.1):
    return int(base_seconds * random.uniform(1 - jitter, 1 + jitter))

def get_user(user_id):
    key = f"user:v1:{user_id}"
    cached = redis.get(key)
    if cached == NOT_FOUND:
        return None                               # cached miss
    if cached is not None:
        return json.loads(cached)
    user = db.find_user(user_id)
    if user is None:
        redis.set(key, NOT_FOUND, ex=60)          # short negative TTL
        return None
    redis.set(key, json.dumps(user), ex=ttl(3600))
    return user

A TTL is a promise about staleness

Write the TTL next to the business rule it satisfies, for example "prices may be up to 5 minutes old on listing pages; checkout always reads the database". It stops TTLs from being tweaked randomly.

त्वरित जाँच: What problem does negative caching solve?

  • Repeated lookups for keys that do not exist hitting the database every time
  • Values that are too large
  • Keys that never expire
  • Encrypting cached data
Answer

Repeated lookups for keys that do not exist hitting the database every time — Caching "not found" briefly protects the origin from repeated misses on absent keys.