Coding problem · Medium · Design & Data Structures

Key-Value Store with TTL

Medium Practical tasks Seen at Amazon, Stripe, Shopify, Datadog

Build an in-memory key-value store where every entry has a time-to-live. Time is passed in (milliseconds) so behaviour is deterministic.

  • set(key, value, ttlMs, nowMs) stores value; it expires at nowMs + ttlMs. Setting an existing key replaces its value and expiry.
  • get(key, nowMs) returns the value, or null if missing or expired (an entry is expired when nowMs >= expiresAt).
  • count(nowMs) returns how many keys are not expired at nowMs.

Example 1

Input: ["TTLStore","set","get","get","count"]
[[],["a","1",100,0],["a",50],["a",100],[100]]
Output: [null,null,"1",null,0]

Hints

Hint 1

Store (value, expiresAt) per key.

Hint 2

get can lazily delete expired entries. For count, think about how real caches avoid scanning everything (expiry heaps, sampled eviction).

Write and run your solution

Loading the editor… (JavaScript is required to run code in your browser.)

Solution and explanation

Show the solution

Time O(1) get/set, O(n) count · Space O(n)

Keep a map key → (value, expiresAt). get checks expiry and deletes stale entries lazily. count here scans and purges expired keys (O(n)); production caches combine lazy deletion with periodic cleanup — Redis samples random keys with a TTL, and a min-heap ordered by expiresAt lets you purge in O(log n) per expired key.

Reference solution

class TTLStore {
  constructor() {
    this.items = new Map(); // key -> { value, expiresAt }
  }

  set(key, value, ttlMs, nowMs) {
    this.items.set(key, { value, expiresAt: nowMs + ttlMs });
  }

  get(key, nowMs) {
    const e = this.items.get(key);
    if (!e) return null;
    if (nowMs >= e.expiresAt) {
      this.items.delete(key);
      return null;
    }
    return e.value;
  }

  count(nowMs) {
    for (const [k, e] of this.items) if (nowMs >= e.expiresAt) this.items.delete(k);
    return this.items.size;
  }
}

Follow-up questions

  • Bound memory: combine TTL with LRU eviction.
  • Make it safe for concurrent access.
  • Use a heap of expiry times to purge without scanning.