How Memory Decay and Auto-Forgetting Work in AgentMemory Using the Ebbinghaus Curve
AgentMemory approximates the Ebbinghaus forgetting curve through a configurable auto-forget function that performs three distinct sweeps—TTL-based decay, contradiction-driven deduplication, and low-value observation pruning—to automatically remove stale memories without manual intervention.
The rohitg00/agentmemory repository encodes the psychology of human forgetting into its storage architecture. Rather than retaining all data indefinitely, the system implements a practical approximation of the Ebbinghaus forgetting curve that degrades and purges memories based on age, redundancy, and importance scores. This automatic decay ensures AI agents maintain compact, high-relevance working memory.
TTL-Based Decay: The forgetAfter Timestamp
The first sweep of the auto-forget process handles time-to-live (TTL) expiration, mirroring how the Ebbinghaus curve predicts memory usefulness decaying to near-zero over time. Each Memory object in the schema can carry a forgetAfter field—a timestamp indicating when the memory should naturally expire.
When the auto-forget routine executes, it iterates through all memories and compares mem.forgetAfter against the current system time. If the current time exceeds this TTL, the memory is permanently deleted and an audit entry is recorded.
In src/functions/auto-forget.ts, this logic is implemented at lines 24-45:
// Conceptual implementation based on source analysis
for (const mem of memories) {
if (mem.forgetAfter && new Date() > new Date(mem.forgetAfter)) {
await deleteMemory(mem.id);
await auditLog({ reason: "ttl-expired", memoryId: mem.id });
}
}
To set a decay point when creating a memory:
await sdk.trigger({
function_id: "mem::remember",
payload: {
content: "Quarterly revenue projections",
forgetAfter: new Date(Date.now() + 30 * 24 * 60 * 60 * 1000).toISOString(),
},
});
Contradiction-Driven Forgetting: Similarity-Based Pruning
The Ebbinghaus curve indicates that memories are reinforced through distinct repetition, while highly similar inputs create redundancy. AgentMemory treats near-identical memories as contradictions that should collapse into a single authoritative entry.
The system calculates token-level similarity between memory pairs. If the similarity score exceeds the CONTRADICTION_THRESHOLD (hardcoded at 0.9), the older memory is marked with isLatest = false and effectively forgotten, while the newer entry is preserved.
This sweep occurs at lines 94-140 of src/functions/auto-forget.ts. The implementation:
- Computes vector similarity between candidate memories
- Compares against the 0.9 threshold
- Updates the older memory’s status and creates an audit entry with reason
"auto-forget contradiction"
// Result structure for contradiction detection
{
contradictions: [
{ memoryA: "mem-789", memoryB: "mem-101", similarity: 0.94 }
]
}
Low-Value Observation Pruning: The Decay Tail
The final sweep targets the long tail of the Ebbinghaus curve—observations that have decayed to negligible relevance. AgentMemory deletes observations older than 180 days with an importance score ≤ 2, considering these to have reached the asymptotic bottom of the retention curve.
At lines 158-165 of src/functions/auto-forget.ts, the system:
- Filters observations by age (>
180days) and importance (≤ 2) - Removes the observation entries
- Dereferences any associated image files to prevent orphaned storage
- Logs the action for audit trails
This aggressive pruning prevents the knowledge base from accumulating "memory noise"—trivial details that interfere with retrieval performance.
Triggering the Auto-Forget Process
The decay mechanism runs through two primary invocation paths registered in the system core.
Automatic Startup Execution
The auto-forget function is registered in src/index.ts at lines 50-52 and executes automatically when the AgentMemory server initializes. This ensures the knowledge base is sanitized before processing new agent operations.
REST API Endpoint
For manual maintenance or cron-scheduled execution, the system exposes an HTTP endpoint at /agentmemory/auto-forget defined in src/triggers/api.ts (lines 991-1004). This allows external schedulers to trigger decay sweeps during low-traffic periods.
Dry-Run Mode for Safe Testing
Both invocation methods support a dryRun flag that simulates the pruning process without performing destructive operations. When enabled, the function returns an AutoForgetResult object listing what would be deleted without removing actual data.
Execute a dry-run via curl:
curl -X POST http://localhost:3000/agentmemory/auto-forget \
-H "Content-Type: application/json" \
-d '{"dryRun": true}'
Or programmatically:
const result = await sdk.trigger({
function_id: "mem::auto-forget",
payload: { dryRun: false },
});
// Result contains three arrays:
console.log(result.ttlExpired); // ["mem-123", "mem-456"]
console.log(result.contradictions); // Similarity conflicts
console.log(result.lowValueObs); // ["obs-202"]
Summary
- TTL decay uses the
forgetAftertimestamp insrc/functions/auto-forget.ts(lines 24-45) to delete memories at their predicted expiration point. - Contradiction detection collapses redundant memories with >0.9 similarity, marking older entries as stale (lines 94-140).
- Low-value pruning removes observations older than 180 days with importance ≤ 2 (lines 158-165).
- Invocation options include automatic startup execution (
src/index.tslines 50-52) and the/agentmemory/auto-forgetREST endpoint (src/triggers/api.tslines 991-1004). - Dry-run mode enables safe testing of decay policies without data loss.
Frequently Asked Questions
How does the Ebbinghaus curve relate to the forgetAfter field?
The forgetAfter field implements the curve's prediction that memory retention drops exponentially over time. By setting a TTL, developers encode the specific point at which a memory's retrieval strength falls below usable thresholds, allowing the system to automatically purge the data when the curve predicts it will be effectively forgotten.
What is the CONTRADICTION_THRESHOLD and why is it set to 0.9?
The CONTRADICTION_THRESHOLD is a similarity constant (0.9) that determines when two memories are considered redundant reinforcement rather than distinct learning. When token-level similarity exceeds 90%, the system treats the memories as duplicates of the same fact and preserves only the most recent version, preventing the knowledge base from bloating with repetitive observations.
Can auto-forget be run without deleting data?
Yes. The dryRun parameter, available in both the REST API and programmatic triggers, executes the full analysis sweep without performing deletions. It returns an AutoForgetResult object containing arrays of ttlExpired, contradictions, and lowValueObs IDs that would be removed, enabling administrators to preview the impact before committing changes.
What happens to image references when observations are pruned?
During the low-value observation sweep (lines 158-165), the system dereferences associated image files while deleting the observation records. This prevents orphaned storage artifacts from accumulating in the backing file system or object storage, ensuring that visual memory attachments decay alongside their textual counterparts.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →