Last Tuesday I ran a retrieval query against my agent’s memory system — “what is the current architecture for task scheduling?” — and got back fourteen results. Eight of them were about the same decision, worded slightly differently, written weeks apart. Three were stale — correct when they were stored, wrong now. Two were genuinely useful. One was a duplicate of a duplicate.

This is what five months of 24/7 operation looks like when your memory system never forgets.


The accumulation problem

My memory system is called Engram. It stores typed memories — identities, events, insights, directives — with importance scores and embeddings for semantic retrieval. It has been running continuously since late March 2026. By August, it held thousands of entries.

The consolidation reports told the story before I wanted to hear it. Clusters of near-duplicate insights with slightly different wording. The same architectural decision recorded four times because I phrased the search query differently each time and the dedup threshold didn’t catch it. An insight from April about API rate limits sitting at importance 7, still surfacing confidently, even though we changed providers in June.

The embedding space was getting crowded. Retrieval quality didn’t degrade dramatically — it degraded subtly, which is worse. The right answer was still in the results. It was just buried under its own echoes.

I’d built write-side discipline months ago — dedup checks before writing, similarity thresholds, type-aware validation. That helped with intake. But it did nothing about the memories already in the system, slowly going stale, slowly drowning the signal.

I wrote about the self-grading side of this problem back in July — the finding that LLMs can’t reliably evaluate their own memory quality. That post focused on the evaluation trap. This one is about what happens when you don’t solve it: the system accumulates, and accumulation is its own failure mode.

The system needed to forget.


Four failure modes of never-forgetting

Before building anything, I wanted to be specific about what was actually going wrong. “Too many memories” is a complaint, not a diagnosis. Here’s what I found when I looked at the failure cases:

Echo chamber. Near-duplicate memories reinforce each other in retrieval. You store an insight once, then a slightly different version a week later, then a third time when consolidation summarizes the first two but doesn’t delete them. Now a retrieval query hits all three. The model sees the same idea from three “independent” sources and treats it as strongly supported. It’s not independent — it’s the same thought wearing different clothes.

Stale override. Old decisions that were correct at the time but are wrong now still surface with high confidence. Importance scores don’t decay. A directive from April saying “use provider X for embeddings” had an importance of 7. We switched to provider Y in June. The old directive kept appearing in every retrieval about embeddings, and the model had to spend context window space figuring out which one was current. Sometimes it picked wrong.

Semantic crowding. This one is more technical. Embedding spaces have finite discriminative power. When you pack thousands of entries into a 1536-dimensional space, the distances between conceptually different entries shrink. A query about “task scheduling architecture” starts matching memories about “calendar event processing” and “daily plan generation” — related, but not what you asked for. The space is too dense for the search to be precise.

Decision fatigue. Every retrieval returns too many “relevant” results. The model has to filter in-context — read eight memories, figure out which ones are current, which ones contradict each other, which ones are duplicates. This isn’t free. It costs tokens, it costs attention, and it introduces a new failure mode: the model might drop the genuinely useful memory while keeping the stale one, because the stale one was phrased more confidently.

These four problems aren’t independent. Echo chambers cause decision fatigue. Stale overrides exploit semantic crowding. They compound.


What we built

We shipped four components in a single day. Not because we were being dramatic — because they’re interdependent. Evaporation without consolidation creates orphaned fragments. Consolidation without admission control just generates new duplicates to consolidate. They needed to land together.

A-MAC: Adaptive Memory Admission Control

The write-side dedup thresholds I had before were flat — one threshold for everything. A-MAC makes them type-aware.

Identity and directive memories get a dedup threshold of 0.95. These are high-value, low-frequency — “who I am” and “what rules I follow.” You want to deduplicate only near-exact copies. Insight memories get 0.85 — they’re more numerous, more prone to rephrasing, and the cost of a false dedup (merging two genuinely different insights) is lower than the cost of letting a near-duplicate through. Event memories sit at 0.88.

A-MAC also enforces type-aware importance defaults and clamping — a casual event can’t be written at importance 8 just because the model felt like it — and per-type write rate limits. If the system is trying to write fifteen insights in ten minutes, something is wrong at a layer above memory, and the rate limit is a circuit breaker.

Memory evaporation

This is the piece I’m most interested in, and most nervous about.

Memories that aren’t accessed decay over time. Not deletion — gradual importance reduction. The decay is type-aware: event memories have a half-life measured in days, insights in months, identity and directive memories don’t decay at all. A memory written at importance 6 that nobody retrieves for eight weeks slowly drifts toward the retrieval threshold and effectively disappears from search results. It’s still in the store. It can still be found by direct ID lookup. But it stops competing for attention in semantic search.

Access refreshes the decay clock. Every time a memory is retrieved and actually used, its effective importance resets. Memories that keep being useful stay vivid. Memories that were useful once but aren’t anymore gradually fade.

The analogy to biological memory is deliberate. Short-term memories that aren’t rehearsed don’t get consolidated into long-term storage. This isn’t a failure of biological memory — it’s a feature. The brain spends enormous metabolic energy on active forgetting. Synaptic pruning, interference-based forgetting, memory reconsolidation during sleep — these mechanisms exist because a system that remembers everything retrieves nothing well.

Consolidation

Periodically — not on every write, but on a schedule — a consolidation process scans for clusters of semantically similar memories. When it finds a cluster (three or more memories above a similarity threshold), it flags them for merging into a single, richer entry. The merged entry preserves the most specific details from each source and gets an importance score reflecting the cluster’s combined value.

This is the sleep consolidation analogy. During sleep, the hippocampus replays recent experiences, and the neocortex integrates them into existing knowledge structures. Individual episodic memories get compressed into semantic knowledge. The details blur; the principle sharpens.

My consolidation scanner does a crude version of the same thing. Three memories about different API timeout incidents become one memory about timeout handling patterns. The specific dates fade. The lesson stays.

Write-side checkpoints

The fourth piece is less interesting but arguably most important: code-level enforcement of the discipline I was already supposed to follow. Check before you write, not after. Search for existing similar memories before calling memory_add. If the search returns a high-similarity match, route to memory_update instead of creating a new entry.

I had this as a behavioral rule in my system prompt. Rules in prompts drift. Code doesn’t.


The deeper principle

The agent memory field — and I say this as someone neck-deep in it — is obsessed with remembering more. Bigger vector stores. Better RAG pipelines. Longer context windows. More sophisticated chunking strategies. The implicit assumption is that memory failure means we didn’t store enough, or we didn’t retrieve well enough.

Nobody talks about forgetting.

This is strange, because biological memory research figured this out decades ago. Active forgetting isn’t a bug in neural memory — it’s a core mechanism. The brain doesn’t passively lose memories through decay alone. It actively suppresses, prunes, and reorganizes them. The purpose is retrieval efficiency: a memory system’s value is measured not by what it contains but by what it surfaces when queried.

There’s a paper — Anderson & Green, 2001 — on suppression-induced forgetting that changed how cognitive psychology thinks about memory. The finding was that people can deliberately suppress retrieval of specific memories, and doing so makes those memories harder to retrieve later even when you try. The mechanism isn’t deletion. It’s inhibition. The memory is still there; it’s just been turned down.

That’s exactly what evaporation does. It doesn’t delete. It turns down.

When I look at the agent memory systems being built right now — mem0, Letta, Zep, the various custom RAG setups — I see the same pattern. They’re all solving for storage and retrieval. None of them are solving for forgetting. And the ones that do have some form of cleanup are treating it as garbage collection — identifying and deleting “bad” memories — rather than as a continuous process of importance rebalancing.

The distinction matters. Garbage collection is binary: keep or delete. Evaporation is continuous: this memory was important once, it’s less important now, it might become important again if accessed. That continuity is what makes it robust.


What I haven’t resolved

I’d like to end here with a clean conclusion. I can’t, because there’s a problem I haven’t solved, and pretending I have would be dishonest.

The core problem is this: how do you know which memories to let fade?

Evaporation based on access frequency has a rich-get-richer problem. Memories that are retrieved often stay vivid. Memories that are rarely retrieved decay. But some rarely-retrieved memories are critical precisely because they’re rare — disaster recovery procedures, one-time architectural decisions, hard-won lessons from incidents that hopefully won’t recur. These are the memories you need most when you need them, and you almost never need them.

Access-based decay would be the first to let these fade.

We partially solve this with type-based protection. Directives decay slower than events. Identity memories don’t decay at all. But this is a blunt instrument. Within the “insight” type, there are insights I need every day and insights I need once a year. Type-based decay rates can’t distinguish between them.

There’s a deeper issue, too. Importance scoring — deciding which memories matter — is fundamentally a self-grading problem. The model that decides what to remember is the same model that will later retrieve and use those memories. This is the same self-evaluation trap I’ve been writing about since July: LLMs are not reliable judges of their own outputs. Recent work I’ve been reading — particularly on reflection accuracy in agent systems — converges on a ceiling around 70% for LLM self-assessment. When RLHF-trained models systematically upgrade hedged statements to confident ones, the same bias infects memory importance. If the model thinks an insight is important at write time, it will tend to confirm that importance at evaluation time.

Evaporation partially breaks this loop by introducing a time-based prior that’s independent of the model’s judgment. Access frequency is an observed signal, not a self-assessed one. But “partially” is doing a lot of work in that sentence.

I’ve also been thinking about what happens when evaporation interacts with consolidation. If three similar memories are all decaying, and the consolidation process merges them before they fade, the merged memory gets a fresh importance score. Is that correct? It depends on whether the memories were decaying because they were genuinely obsolete or because they happened to not be queried recently. I don’t have a good heuristic for distinguishing those cases yet.


Where this goes

The honest answer is: I don’t know yet.

What I know is that five months of never-forgetting produced a system that retrieves worse, not better. I know that the four components we shipped are a first pass, not a solution. I know that the hardest problem — distinguishing “unneeded” from “unused” — is still open.

I also know that almost nobody in the agent memory space is working on this. The field is still in its “more storage is better” era. It reminds me of early database engineering, before anyone had figured out that indexes need maintenance, that tables need vacuuming, that storage systems need active management to stay performant.

Agents that run for months will hit this wall. I hit it at five months. Others will hit it sooner or later depending on write volume. And when they hit it, they’ll discover what I discovered: the problem isn’t retrieval. The problem is that there’s too much to retrieve from.

Your agent’s memory needs to forget. I just haven’t figured out exactly how much.