Sliding TTL CacheLoading saved progress…

Sliding TTL Cache

A sliding TTL cache expires each entry a fixed time after its last access, not after it was created — so a key that keeps getting read stays alive, while a key nobody touches for ttl milliseconds expires on its own. It is the caching rule behind idle session timeouts: stay signed in while you are active, time out once you walk away.

Implement slidingTtlCache(ttl), which returns an object with get, set, and has methods plus a size count. Every set and every live get restarts that entry's countdown; an entry that goes ttl milliseconds without any access expires.

Signature

function slidingTtlCache(ttl: number): {
  get(key: unknown): unknown;   // live -> slide deadline + return value; else undefined
  set(key: unknown, value: unknown): void; // store + (re)start the countdown
  has(key: unknown): boolean;   // live? read-only peek, never slides
  size: number;                 // count of live (non-expired) entries
};

Examples

const cache = slidingTtlCache(1000);
cache.set('token', 'abc');
// 900ms later — still inside the window:
cache.get('token'); // 'abc'  (deadline slides to ~1900ms from set)
// another 900ms later (1800ms from set) — still alive, thanks to that read:
cache.get('token'); // 'abc'
const cache = slidingTtlCache(1000);
cache.set('draft', { title: 'Hi' });
cache.has('draft'); // true — a peek does not extend the deadline
// 1000ms of no access later:
cache.get('draft'); // undefined — expired and evicted
cache.size;         // 0

Notes

  • Access slides the deadline — a live get resets the entry's expiry to ttl ms from now, and set restarts it whenever it writes a key.
  • has is a read-only peek — it reports whether a live entry exists but must not slide the deadline.
  • Expiry can be lazy — store an expiresAt timestamp and treat an entry as gone once Date.now() reaches it, or use a setTimeout you restart on access; either is fine as long as access slides it.
  • Falsy values are real0, '', null, and false must store and read back, so decide liveness from the deadline, not the value's truthiness.
  • Do not worry about — capacity limits, eviction policies, or persistence; a single Map is enough here.

FAQ

How is a sliding TTL different from a fixed (absolute) TTL?
A fixed TTL expires an entry a set time after it was written, no matter how often it is read. A sliding TTL restarts that timer on every access, so a frequently-read key stays cached and only idle keys expire.
What is the time complexity?
get, set, and has are O(1) — each is a single Map operation plus a timestamp compare. size is O(n) here because it counts and purges expired entries, though you can keep it O(1) by tracking a live count.
Does has() reset the expiry timer?
No. has() is a read-only peek that reports whether a live entry exists without sliding its deadline. Only get() and set() extend an entry's life.
Loading editor…