Memory Decay and Garbage Collection
Forget old, low-relevance memories on a schedule so the index stays focused.
Memory Decay and Garbage Collection is a free AI Agents lesson on CoddyKit — lesson 4 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the AI Agents learning path, one of 4 lessons in the course, and your progress syncs across the web and the CoddyKit app.
Memory Grows Without Bound
Without active maintenance, your memory store keeps growing. Old, irrelevant memories pollute retrieval and waste storage.
Memory needs garbage collection just like any other resource.
Why Delete Memories?
- Privacy — comply with GDPR/CCPA delete requests
- Relevance — old facts are less likely correct now
- Cost — vector storage adds up at scale
- Quality — bloated indexes dilute search relevance
Strategy 1: TTL
Set an expiration timestamp on each memory:
ALTER TABLE semantic_facts ADD COLUMN expires_at TIMESTAMPTZ;
-- short-lived
INSERT INTO semantic_facts (..., expires_at) VALUES (..., NOW() + INTERVAL '7 days');
-- garbage collect
DELETE FROM semantic_facts WHERE expires_at < NOW();Strategy 2: Time-Based Decay
Decrease confidence with age — older memories are deprioritised:
import math
def decayed_confidence(original, age_days, half_life_days=30):
return original * math.exp(-age_days * math.log(2) / half_life_days)
# Then retrieval filters: WHERE decayed_confidence > 0.3
for age in [0, 30, 60, 90]:
print(f"Age {age} days -> confidence {decayed_confidence(1.0, age):.3f}")
Strategy 3: Usage-Based Decay
Memories that are never retrieved are not useful — delete them after a grace period:
ALTER TABLE semantic_facts ADD COLUMN last_used_at TIMESTAMPTZ DEFAULT NOW();
-- update on retrieval
UPDATE semantic_facts SET last_used_at = NOW() WHERE id = ANY(:retrieved_ids);
-- gc
DELETE FROM semantic_facts WHERE last_used_at < NOW() - INTERVAL '90 days';Strategy 4: Capacity Cap Per User
Limit memories per user; when full, evict the least-used:
MAX_FACTS = 500
SELECT COUNT(*) FROM semantic_facts WHERE user_id = %s;
-- if > MAX_FACTS: delete oldest unusedCompaction: Merge Similar Memories
Multiple memories may say the same thing differently. Periodically cluster and merge:
def compact(user_id):
facts = all_facts(user_id)
clusters = cluster_by_embedding(facts, threshold=0.85)
for cluster in clusters:
merged = llm.invoke(f'Merge these into one canonical statement: {cluster}')
replace_with_merged(cluster, merged)Contradiction Resolution
If two memories contradict, mark older as obsolete:
def resolve(user_id, new_fact):
similar = retrieve(user_id, new_fact, k=5)
for s in similar:
if llm_says_contradicts(s, new_fact):
mark_obsolete(s.id)
save(new_fact)Strategy 5: Importance Weighting
Some memories matter more than others. Score each:
importance_prompt = 'Rate the importance of this fact for future interactions (0-1):\n{fact}'
for fact in facts:
score = float(llm.invoke(importance_prompt.format(fact=fact)).content)
update_importance(fact.id, score)
# Retrieval: weight by importance and recencyLetta-Style Summarisation
Letta (MemGPT) compresses old archival memory by summarising blocks of related facts when storage fills up:
if archival_size > LIMIT:
block = oldest_facts(50)
summary = summarise(block)
replace(block, summary)User-Triggered Deletion
Give users a "forget about me" button. On click:
def forget_user(user_id):
conn.execute('DELETE FROM semantic_facts WHERE user_id = %s', (user_id,))
conn.execute('DELETE FROM episodes WHERE user_id = %s', (user_id,))
vector_db.delete(filter={'user_id': user_id})Soft Delete vs Hard Delete
For audits, prefer soft delete (mark as deleted, keep encrypted) until retention period passes, then hard delete:
ALTER TABLE semantic_facts ADD COLUMN deleted_at TIMESTAMPTZ;
-- queries always: WHERE deleted_at IS NULLScheduled GC Jobs
Run GC on a schedule (cron, daily worker). Don't do heavy GC inline — it adds latency for users:
# Daily cron at 03:00 UTC
for user_id in all_users():
decay_confidence(user_id)
delete_expired(user_id)
compact_clusters(user_id)Why Decay?
Why decay memory confidence over time?
Recap
TTL, decay, usage-based eviction, capacity caps, compaction, contradiction resolution, user-triggered deletion. Memory needs a janitor; build one.
Frequently asked questions
Is the “Memory Decay and Garbage Collection” lesson free?
Yes — the full text of “Memory Decay and Garbage Collection” is free to read here on the web, and the AI Agents course includes 4 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the AI Agents course, upgrade to CoddyKit PRO.
What will I learn in “Memory Decay and Garbage Collection”?
Forget old, low-relevance memories on a schedule so the index stays focused. You practise AI Agents with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.
Do I need any experience to start AI Agents?
No prior experience is required. AI Agents on CoddyKit is structured for beginners through advanced learners; this is — lesson 4 of 4, so you can start here or from the beginning and move at your own pace.
How long does the “Memory Decay and Garbage Collection” lesson take?
Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.
Can I write and run code in this AI Agents lesson?
Yes. Every AI Agents lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.
All lessons in this course
- Episodic Memory (Per-Session History)
- Semantic Memory (Vectorised Facts)
- Procedural Memory (Skill Library)
- Memory Decay and Garbage Collection