How to Configure Memory Decay and Retention Policies in ai-memory

ai-memory uses a configurable decay engine that applies exponential salience reduction to episodic pages, controlled through a [decay] table in .ai-memory.toml with optional pinning and TTL overrides for fine-grained retention control.

Memory decay and retention policies in the akitaonrails/ai-memory repository keep your knowledge base fresh while preserving critical information. The system targets episodic pages—raw observations generated by agents—and applies configurable aging algorithms that you can tune per project or override per page.

The Decay Configuration File

All decay settings live in a project-level .ai-memory.toml file. The server reads this configuration once at startup via Config::load() in crates/ai-memory-mcp/src/server.rs (lines 298–385).

Core Decay Parameters

The [decay] table supports these fields:

Parameter Default Purpose
lambda 0.02 day⁻¹ Per-day exponential decay rate for salience
observation_retention_days 0 (disabled) TTL for raw observation rows before hard deletion
observation_prune_batch varies Maximum rows removed per forget-sweep
breadth_weight 0.0 Bonus salience for pages with many inbound links
inactivity_days 7 Minimum idle time before a page becomes eligible for decay

Sample Configuration


# .ai-memory.toml

[decay]
lambda = 0.02
observation_retention_days = 30
observation_prune_batch = 500
breadth_weight = 0.1
inactivity_days = 7

The server injects these values into the DecayParams struct via with_decay_params in crates/ai-memory-mcp/src/server.rs (lines 1777–1784).

How the Decay Algorithm Works

The decay engine lives in crates/ai-memory-store/src/decay.rs. It computes salience—a score representing a page's relevance—and reduces it exponentially based on age.

Exponential Salience Decay

The function salience_after_feedback applies the formula using your configured lambda:

// Conceptual implementation based on decay.rs
new_salience = current_salience * exp(-lambda * days_since_access)

A smaller lambda slows decay; larger values make pages become stale faster.

The Forget-Sweep Process

The decay system runs periodically (default: hourly) and performs these operations:

  1. Candidate selectiondecay_candidates in crates/ai-memory-store/src/reader.rs enumerates pages eligible for decay, excluding pinned rows (checked in row_to_decay_candidate, lines 1116–1120)
  2. Salience recalculation — Pages with updated salience below threshold become decay tombstones
  3. TTL enforcement — Pages with expired expires_at timestamps are removed regardless of salience (handled in soft_delete_for_decay_if_latest in crates/ai-memory-store/src/ops.rs, lines 2077–2081)
  4. Batch pruning — Raw observations older than observation_retention_days are hard-deleted, capped by observation_prune_batch

Retention Mechanisms Beyond Decay

Pinning Pages for Permanent Retention

Pinned pages are immune to all decay calculations. Use this for architecture decisions, API contracts, or any knowledge that must persist indefinitely.

CLI approach:

ai-memory pin docs/important/architecture.md

Internally, this sets pinned = true on the pages row. The decay_candidates query automatically excludes these rows.

Front-matter approach:

---
title: "Core System Architecture"
pinned: true
---

The pinning logic is implemented in crates/ai-memory-wiki/src/wiki.rs (line 864).

Per-Page TTL with expires_at

Override decay behavior for temporary content using a timestamp:

---
title: "Sprint 47 Experiment Notes"
expires_at: "2027-01-01T00:00:00Z"
---

When the forget-sweep encounters this page after the timestamp, it removes the page immediately—salience scores are ignored.

Breadth-Weighted Salience

The breadth_weight parameter rewards pages referenced from many contexts. If set to 0.1, a page with 10 unique inbound links receives a salience bonus proportional to that count. This preserves "hub" pages that serve as connection points in your knowledge graph.

Runtime Configuration Updates

The MCP server exposes an admin endpoint to adjust decay without restarting:

POST /admin/config
Content-Type: application/json

{
  "decay_params": {
    "lambda": 0.015,
    "observation_retention_days": 60,
    "observation_prune_batch": 1000,
    "breadth_weight": 0.2,
    "inactivity_days": 10
  }
}

The server merges this payload into its active DecayParams via with_decay_params in server.rs.

Tuning Strategies for Different Use Cases

Aggressive pruning for high-volume agents:

[decay]
lambda = 0.05
observation_retention_days = 7
observation_prune_batch = 2000

Conservative retention for long-lived knowledge bases:

[decay]
lambda = 0.005
breadth_weight = 0.15
inactivity_days = 30

Hybrid: permanent core, decaying experiments:

  • Pin docs/architecture/ and docs/api/
  • Set expires_at on experiment notes
  • Use default lambda for everything else

Summary

  • Configure decay parameters in .ai-memory.toml under the [decay] table; the server loads these at startup via Config::load() in crates/ai-memory-mcp/src/server.rs
  • The exponential decay algorithm in crates/ai-memory-store/src/decay.rs uses lambda to control salience reduction speed
  • Pin critical pages via CLI (ai-memory pin) or pinned: true in front-matter to exclude them from all decay
  • Set expires_at timestamps for temporary content that should disappear regardless of access patterns
  • Adjust breadth_weight to preserve well-connected "hub" pages in your knowledge graph
  • Use the /admin/config MCP endpoint to update parameters at runtime without restarting

Frequently Asked Questions

What happens if I don't create an .ai-memory.toml file?

The server uses default values: lambda = 0.02, observation_retention_days = 0 (disabled), and breadth_weight = 0.0. Decay proceeds with these conservative defaults, but no raw observations are automatically pruned.

Can I disable decay entirely?

Set lambda = 0.0 and ensure no pages have expires_at timestamps. Alternatively, pin all pages you want to preserve—though this is impractical for large systems. There is no global "disable decay" flag; you must configure parameters to effectively neutralize it.

What's the difference between a decay tombstone and hard deletion?

A decay tombstone marks a page as obsolete but preserves its history and relationships; it becomes invisible to normal queries but remains in storage. Hard deletion permanently removes data and occurs only for raw observations past their observation_retention_days TTL or pages with expired expires_at timestamps.

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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →