How to Implement Automatic Memory Forgetting
Before You Start
Forgetting requires that your memories track access history, because activation decay is computed from when and how often each memory was retrieved. If your memory store only records creation time without tracking subsequent accesses, add access logging first. Each time a memory appears in a retrieval result that is actually used, append the current timestamp to its access history.
You also need to decide your retention policy. Some domains require that no data is ever permanently deleted, which means you need an archival tier rather than true deletion. Other domains benefit from permanent removal of stale entries. Make this decision before building the pipeline, because it affects the architecture of your storage system.
Step-by-Step Implementation
Use power-law decay rather than exponential decay, because power-law matches observed human memory behavior and produces more gradual forgetting with a longer tail. The decay function computes base-level activation from the memory's access history using ACT-R's base-level learning equation. The key parameter is the decay rate d, which controls how quickly activation drops. A value of 0.5 matches human memory data. Higher values like 0.7 produce faster forgetting for domains where information changes rapidly. Lower values like 0.3 preserve memories longer for stable knowledge domains.
import math
import time
def compute_activation(access_times, decay=0.5):
now = time.time()
if not access_times:
return -float('inf')
total = 0.0
for t in access_times:
age = max(now - t, 1.0)
total += age ** (-decay)
return math.log(total)The forgetting threshold is the activation value below which a memory is considered forgotten. Memories above this threshold remain in the active retrieval index. Memories below it become candidates for archival or deletion. The right threshold depends on your store size and retrieval patterns. Start by computing activation values for all memories in your current store, then set the threshold at a percentile that would remove the bottom 10% to 20% of memories. Monitor the effect on retrieval quality and adjust.
FORGET_THRESHOLD = -3.0
def should_forget(memory, decay=0.5):
activation = compute_activation(memory['access_times'], decay)
return activation < FORGET_THRESHOLDNot all memories should be subject to the same forgetting rules. Memories with high confidence scores, those corroborated by multiple independent sources, should decay more slowly. Memories that serve as knowledge graph hubs, connecting many other memories through shared entities, are structurally important even if they have not been directly retrieved recently. Apply a decay rate modifier based on importance: high-importance memories use a lower effective decay rate, which means they persist longer before reaching the forgetting threshold.
def effective_decay(memory, base_decay=0.5):
confidence = memory.get('confidence', 5.0)
corroboration = memory.get('corroboration_count', 1)
entity_count = len(memory.get('entities', []))
importance = (confidence / 10.0) * 0.5
importance += min(corroboration / 5.0, 1.0) * 0.3
importance += min(entity_count / 10.0, 1.0) * 0.2
# scale decay: high importance gets slower decay
return base_decay * (1.0 - importance * 0.6)When a memory falls below the forgetting threshold, move it to cold storage rather than deleting it immediately. Cold storage should preserve the full memory content, metadata, and access history so the memory can be restored to the active index if needed. Remove the memory's vector embedding from the active search index to reduce retrieval candidates, but keep the raw data accessible through an explicit archive query. This two-tier approach gives you the retrieval performance benefits of forgetting with the safety net of recoverable data.
def archive_memory(memory, active_store, archive_store, vector_index):
archive_store.put(memory['id'], {
'content': memory['content'],
'metadata': memory,
'archived_at': time.time(),
'reason': 'activation_decay'
})
vector_index.remove(memory['id'])
active_store.delete(memory['id'])Run the forgetting sweep on a regular schedule. Weekly is appropriate for most applications. Nightly sweeps work for high-volume systems that ingest hundreds of memories per day. The sweep iterates through all active memories, computes their current activation with importance-adjusted decay, checks against the forgetting threshold, and archives or deletes memories that qualify. Run during off-peak hours to minimize impact on concurrent retrieval operations.
After each forgetting cycle, track key metrics: how many memories were archived, what their average age and confidence were, and whether retrieval quality changed. If high-quality memories are being forgotten, lower the decay rate or raise the importance thresholds. If the store is still growing faster than forgetting removes entries, lower the forgetting threshold or increase the decay rate. The goal is a steady state where the active store size stabilizes because new memories enter at roughly the same rate that old ones are forgotten.
Permanent Deletion vs Archival
Archival preserves data for potential restoration, which is the safer default. Permanent deletion reduces storage costs further but is irreversible. For applications with compliance requirements like GDPR or HIPAA, you may need both: archival for general lifecycle management and permanent deletion for data subject requests where the right to erasure applies. Adaptive Recall's forget tool supports both modes, with an explicit flag to indicate whether a forget operation should archive or permanently delete.
Tuning the Decay Rate
The decay rate is the single most impactful parameter in your forgetting system. Customer support applications typically use higher decay rates (0.6 to 0.8) because product information changes frequently and old troubleshooting steps become harmful when they reference outdated interfaces. Research and legal systems use lower decay rates (0.3 to 0.4) because historical information retains relevance for years. General-purpose assistants use the default 0.5, which balances recency preference with reasonable retention of established knowledge.
Test different decay rates against your actual retrieval patterns. Store a snapshot of your current results for a set of benchmark queries, change the decay rate, run the forgetting sweep, and compare the new results against the snapshot. If important memories disappear from the results, the decay rate is too high for your domain.
Automatic forgetting, importance scoring, and archival built in. Start with managed memory lifecycle today.
Try It Free