Synthetic Industry

Platform · updated 2026-10-11

Redis as a cache: expiry, eviction and invalidation decide whether users see fresh data

For teams using Redis in front of a database: how expiry is cleared by overwrites, what the memory limit does, why persistence is optional for a cache, and which bounded job fits.

Three settings people confuse

Expiry, eviction and persistence all affect whether a cached value is there, and they are independent. Expiry is per key: a time to live after which the key is deleted. Eviction is global: what Redis does when memory reaches maxmemory. Persistence is about restarts: whether data survives. The Redis documentation says maxmemory is zero, meaning no limit, by default on 64-bit systems, so a cache with no limit grows until the host runs out of memory.

When the limit is set, the policy matters. With noeviction, the documentation says commands that add data return errors while reads still work. The volatile policies evict only keys that have an expiry and behave like noeviction if none do. allkeys policies can evict any key. Choosing a policy is choosing which failure you prefer.

  • Check maxmemory and maxmemory-policy on the instance, not in the config file you remember.
  • Compare hits and misses, evicted keys and expired keys from INFO to see which mechanism removes entries.

Why a refreshed value may never expire

The commonest surprise is that overwriting a key with SET discards its expiry. Code that stores a value with a time to live and later refreshes it with a plain SET leaves a key with no expiry at all, which then survives for ever and can also become immune from volatile eviction. Commands that alter a value in place, such as INCR or HSET, leave the timeout alone. The documentation describes KEEPTTL as the option to retain it, available since Redis 6.0.0.

The remedy is a stated policy: when a value is rewritten, does it get a fresh expiry, keep the old one or none? Tests should check the remaining lifetime after an overwrite.

  • Search for SET calls on cached keys that do not pass an expiry.
  • Test the remaining lifetime of a key before and after an overwrite.

A cache needs no persistence, but needs an owner for invalidation

The persistence page notes that running with no persistence is sometimes used when caching, and that snapshots can lose the latest minutes of writes after a crash. For a pure cache this is acceptable, because the source of truth is the database and entries can be rebuilt. It stops being acceptable when the same instance also holds data that exists nowhere else; the eviction page advises running two separate instances in that case if possible.

The harder problem is invalidation: deleting or refreshing an entry when the database changes. Deleting by pattern with KEYS is warned against in the documentation for large databases, and SCAN may return keys more than once and has weaker guarantees for keys added or removed during the scan. Prefer to track the keys belonging to an object, or version the key.

  • Keep cache-only data and primary data on separate instances where you can.
  • Design invalidation by key, not by pattern.

The bounded job for Redis caches

The stale-cache outcome takes one object type and its Redis keys, maps every code path that changes it, corrects the order of write, commit and invalidate and the expiry handling, and proves it with tests that include a read during an update. It runs on staging with synthetic data and hands back a pull request. It does not tune Redis, change eviction or persistence, clear keys on production, or cover other cache stores.

If several object types are affected, each is its own scope, since each has its own write paths, and several can be quoted together. The price is an untested proposal.

  • Send the object type, the key shape in words and the write paths first.
  • Do not send connection details or cached values.

Sources and limits

  • Redis: Key eviction Checked 2026-10-11.
    • maxmemory defaults to no limit on 64-bit systems; the noeviction policy returns errors for commands that add data at the limit; volatile policies behave like noeviction when no keys have an expiry.
    • keyspace_hits, keyspace_misses, evicted_keys and expired_keys from INFO help judge cache effectiveness.
  • Redis: Persistence Checked 2026-10-11.
    • Persistence can be RDB snapshots, an append-only file, both, or none, and none is sometimes used when caching; RDB can lose the latest minutes of writes after a crash.
  • Redis: EXPIRE Checked 2026-10-11.
    • Overwriting a key with SET clears its timeout, while commands that alter a value in place leave it.
  • Redis: SCAN Checked 2026-10-11.
    • SCAN may return an element more than once and has weaker guarantees for elements added or removed during iteration.