skip to content

In a Redis primary–replica setup where both nodes have `maxmemory` configured, does a replica evict keys on its own when it reaches the limit? Explain what actually causes data to disappear from a replica.

level: seniorimportance: nice to knowfreq 28%

answer

  1. primary evicts, propagates DEL/UNLINK
  2. replica-ignore-maxmemory yes (default, 5.0+)
  3. independent eviction ⇒ divergent replicas
  4. replica RSS > maxmemory: replication buffers
  5. promoted replica starts evicting — set its policy

basics

~10 s

No. By default a replica ignores its own maxmemory for replicated data (replica-ignore-maxmemory yes). The primary evicts and propagates an explicit DEL/UNLINK down the replication stream; the replica just applies it, keeping datasets identical.

solid answer

~50 s

Eviction is a **primary-side decision**. When the primary is over `maxmemory` it selects victims by policy, deletes them, and propagates an explicit `DEL` (or `UNLINK` with lazy-free) to replicas and to the AOF. Replicas apply that deletion like any other write. Since Redis 5.0, `replica-ignore-maxmemory` defaults to `yes`: a replica does not run eviction against its own limit for replicated data. That is deliberate — if replicas evicted independently, each would choose different victims and the datasets would silently diverge, so a read routed to a replica could miss data the primary still holds, and a failover would promote an arbitrarily different keyspace. Consequences to keep in mind: a replica can exceed its configured `maxmemory` (its replication buffer and client output buffers add on top of the dataset), so size replica memory at least as generously as the primary. And when a replica is promoted, it starts making eviction decisions itself — so its policy must already be set correctly, not left as an afterthought.

code

text · 9 lines
text
# on the replica
127.0.0.1:6380> CONFIG GET replica-ignore-maxmemory
1) "replica-ignore-maxmemory"
2) "yes"
127.0.0.1:6380> CONFIG GET maxmemory-policy   # this governs AFTER promotion
1) "maxmemory-policy"
2) "noeviction"                                 # <-- likely wrong for a cache
127.0.0.1:6380> INFO stats
evicted_keys:0                                  # expected on a replica

go deeper

for a junior

Know the headline: the primary evicts and sends a delete to replicas; replicas do not evict by themselves.

for a middle

Name replica-ignore-maxmemory and its default, and explain why a shared deletion stream keeps replicas identical.

for a senior

Add the sizing consequence (replica RSS can exceed maxmemory) and the promotion trap where a replica's policy suddenly governs the dataset.

for a principal

Reason about it as single-writer authority over destructive decisions, and set fleet-wide policy so any node is correctly configured for the role it may be promoted into.

## The rule: primaries decide, replicas obey Redis replication is a stream of write effects. When a primary evicts a key under memory pressure, it does not tell replicas "I am over maxmemory"; it deletes the key locally and propagates an explicit deletion command — `DEL`, or `UNLINK` when lazy-freeing is enabled — into the replication link and the AOF. Replicas execute it as an ordinary replicated write. That design exists to keep replicas byte-identical to the primary. Eviction heuristics are approximate and sampled: if each node independently chose victims, two replicas of the same primary would drop different keys. A read routed to replica A would miss a key that replica B still serves, and a failover would promote a node with an arbitrary subset of the data. Making eviction a single-writer decision at the primary removes that class of divergence entirely. ## `replica-ignore-maxmemory` Since Redis 5.0 the directive `replica-ignore-maxmemory` defaults to `yes` (it was `slave-ignore-maxmemory` before the terminology change). With it enabled, a replica does not perform eviction for replicated data even if its own `used_memory` exceeds its own `maxmemory`. It still honors the limit in one respect: as a *replica*, it is not accepting client writes anyway, so the OOM error path barely applies. The practical implication is that **a replica can legitimately sit above its configured `maxmemory`**. Its footprint is the dataset plus the replication backlog buffer, plus client output buffers for any read traffic it serves, plus the same allocator fragmentation the primary has. So a replica sized exactly like the primary can OOM-kill first. Give replicas at least as much RAM as the primary, and watch `used_memory_rss` rather than trusting the configured cap. Setting `replica-ignore-maxmemory no` re-enables independent eviction. It is almost always a mistake: you trade a memory ceiling for silent divergence. ## Where replicas *do* delete on their own Two cases are worth naming precisely so you do not overstate the rule. **Writable replicas.** With `replica-read-only no`, clients may write directly to a replica. Those locally-written keys are not part of the replicated dataset, and Redis tracks them separately so it can reclaim them without corrupting replication state. This is a niche feature for scratch data; a full resync from the primary wipes such keys, so nothing durable belongs there. **Promotion.** The moment a replica is promoted to primary — by Sentinel, by cluster failover, or by a manual `REPLICAOF NO ONE` — it becomes the node making eviction decisions. Its `maxmemory` and `maxmemory-policy` now govern the whole dataset. If you configured the replica with `noeviction` "because it never evicts anyway", the newly promoted primary will start rejecting writes with OOM errors at exactly the worst moment. **Configure replicas with the same memory settings you want after failover.** ## Expiration is a separate mechanism with the same shape Key expiry follows the same primary-authoritative model: the primary decides a key is expired and propagates an explicit deletion; replicas do not remove expired keys from their own keyspace on their own initiative, though they will hide a logically-expired key from reads. The detailed lazy/active expiry cycle is its own subject — the point relevant here is simply that eviction and expiration are *different* mechanisms that happen to share the propagate-a-DEL design, and neither makes a replica an independent decision-maker. ## Operating checklist - Size replica RAM ≥ primary RAM; replication and output buffers are on top of the dataset. - Leave `replica-ignore-maxmemory` at `yes` unless you have an unusual, well-understood reason. - Give replicas the `maxmemory-policy` you want them to use **after promotion**, and verify it with `CONFIG GET maxmemory-policy` on every node, not just the primary. - Expect `evicted_keys` in `INFO stats` to be ~0 on replicas; evictions show up on the primary. A non-zero counter on a replica means either it was recently a primary or someone disabled the default. - Remember reads served from replicas can see slightly stale data because replication is asynchronous; that is independent of eviction, but it compounds the confusion when someone reports "the key is on one node and not the other" right after a failover.

  • Why would independent eviction on replicas be dangerous?
    Eviction is sampled and approximate, so two replicas of the same primary would pick different victims and their keyspaces would silently diverge from each other and from the primary. Reads spread across replicas would then return inconsistent hit/miss results, and a failover would promote a node holding an arbitrary subset of the data. Routing every deletion through the primary as an explicit DEL keeps all copies identical.
  • A replica shows `used_memory` above its configured `maxmemory`. Is that a bug?
    No — with `replica-ignore-maxmemory yes` a replica does not evict to stay under the cap, and its footprint also includes the replication backlog and client output buffers on top of the dataset. The real risk is the OS OOM-killer, so provision replicas with at least as much RAM as the primary and monitor `used_memory_rss` rather than relying on the configured limit as a guarantee.

saying these in an interview costs you the question

  • Saying each node evicts independently under its own maxmemory, keeping replicas consistent anyway.
  • Assuming a replica sized identically to the primary is safe, ignoring replication and output buffers.
  • Leaving replicas on `noeviction` and being surprised by OOM write errors right after a promotion.
  • Confusing asynchronous replication lag with eviction as the reason a key is missing on a replica.
  • Turning off `replica-ignore-maxmemory` as a routine memory-control measure.

context