# Understanding the Exponential Retention Formula for Memory Decay in ai-memory

> Explore the exponential retention formula in ai-memory. Learn how it calculates memory salience, discounts scores by age and access, and uses breadth weight and user feedback to boost retention.

- Repository: [Fabio Akita/ai-memory](https://github.com/akitaonrails/ai-memory)
- Tags: deep-dive
- Published: 2026-08-22

---

**The exponential retention formula in ai-memory calculates a memory page's salience by exponentially discounting its base score based on chronological age and time since last access, while breadth weight and user feedback provide reinforcing boosts.**

The `ai-memory` library (github.com/akitaonrails/ai-memory) implements a procedural memory system that mimics human forgetting by fading observations that are not reinforced. Central to this mechanism is an exponential decay function defined in [`crates/ai-memory-store/src/decay.rs`](https://github.com/akitaonrails/ai-memory/blob/main/crates/ai-memory-store/src/decay.rs) that continuously evaluates every stored page to decide whether it remains relevant or should be tombstoned. The formula balances natural temporal erosion against signals of continued utility, such as repeated access or positive feedback.

## Core Components of the Decay Formula

The salience score combines two exponential decay factors and a logarithmic reinforcement term:

- **Age-decay**: Applies exponential decay based on `age_days` (days since the page was created or updated).
- **Access-decay**: Applies exponential decay based on `days_since_access` (days since the page was last retrieved).
- **Breadth-weight**: A multiplier `σ` that scales the access component by the logarithm of `access_count`, rewarding pages reused across many distinct sessions.

The implementation in [`crates/ai-memory-store/src/decay.rs`](https://github.com/akitaonrails/ai-memory/blob/main/crates/ai-memory-store/src/decay.rs) expresses this as:

```rust
salience = base_salience * exp(-λ * age_days)
         + σ * log(1 + access_count) * exp(-μ * days_since_access)

```

Where:

- `λ` (lambda) is the daily decay rate for raw age (default approximately `0.03`, or roughly 3% loss per day).
- `μ` (mu) is the daily decay rate for the access component (default approximately `0.01`).
- `σ` (sigma) is the breadth weight coefficient that determines how much multi-session usage amplifies retention.

## Feedback-Driven Salience Adjustments

When a page receives explicit **feedback**—such as a user marking it `Helpful` or `NotHelpful`—the formula adjusts the score via `salience_after_feedback`. This function adds a small bump or penalty proportional to the feedback kind before the time-based decay continues.

Pages marked as **pinned** (e.g., curated slots) bypass decay entirely. The `pinned` flag in the store layer ensures these records are excluded from forget-sweeps regardless of their calculated salience.

## The Forget-Sweep Implementation

The decay logic executes during periodic **forget-sweeps** coordinated across [`crates/ai-memory-store/src/reader.rs`](https://github.com/akitaonrails/ai-memory/blob/main/crates/ai-memory-store/src/reader.rs), [`ops.rs`](https://github.com/akitaonrails/ai-memory/blob/main/ops.rs), and [`crates/ai-memory-wiki/src/wiki.rs`](https://github.com/akitaonrails/ai-memory/blob/main/crates/ai-memory-wiki/src/wiki.rs):

1. **Candidate Selection**: `store.reader.decay_candidates(workspace, project)` queries for pages eligible for evaluation, excluding pinned entries.
2. **Score Recalculation**: For each candidate, the sweep invokes `salience_after_time`, passing the current `DecayParams`, existing salience, `age_days`, `days_since_access`, and `access_count`.
3. **Soft-Delete Trigger**: If the new salience falls below `params.salience_threshold`, the system calls `store.writer.soft_delete_for_decay_if_latest(page_id)` to tombstone the page.
4. **Hard Purge**: After a grace period, [`wiki.rs`](https://github.com/akitaonrails/ai-memory/blob/main/wiki.rs) permanently removes tombstoned records.

## Practical Code Examples

Configure decay parameters and simulate a sweep:

```rust
use ai_memory_store::decay::{DecayParams, salience_after_time, salience_after_feedback, FeedbackKind};

// Initialize default parameters (customizable via config)
let params = DecayParams::default();

// Process feedback to boost a page's standing
let boosted = salience_after_feedback(
    &params,
    Some(current_score),
    FeedbackKind::Helpful,
);

// During a sweep, evaluate each candidate
for candidate in store.reader.decay_candidates(workspace, project).await? {
    let new_salience = salience_after_time(
        &params,
        candidate.current_salience,
        candidate.age_days,
        candidate.days_since_access,
        candidate.access_count,
    );
    
    if new_salience < params.salience_threshold {
        store.writer.soft_delete_for_decay_if_latest(candidate.page_id).await?;
    }
}

```

## Summary

- The **exponential retention formula** models memory usefulness as a combination of age-based and access-based exponential decay.
- **Lambda (λ)** and **mu (μ)** control daily attrition rates (~3% and ~1% respectively), while **sigma (σ)** scales the benefit of repeated access across sessions.
- **Feedback mechanisms** provide immediate salience adjustments via `salience_after_feedback` before decay calculations resume.
- The **forget-sweep** pipeline in [`reader.rs`](https://github.com/akitaonrails/ai-memory/blob/main/reader.rs), [`decay.rs`](https://github.com/akitaonrails/ai-memory/blob/main/decay.rs), and [`ops.rs`](https://github.com/akitaonrails/ai-memory/blob/main/ops.rs) iteratively evaluates pages, soft-deleting those that fall below the configured salience threshold while respecting **pinned** exemptions.

## Frequently Asked Questions

### What is the exact mathematical formula for memory decay in ai-memory?

The implementation in [`crates/ai-memory-store/src/decay.rs`](https://github.com/akitaonrails/ai-memory/blob/main/crates/ai-memory-store/src/decay.rs) calculates salience as `base_salience * exp(-λ * age_days) + σ * log(1 + access_count) * exp(-μ * days_since_access)`. This combines exponential forgetting of the original content with a secondary exponential decay on access patterns, modulated by a logarithmic function of usage frequency.

### How does user feedback alter the retention score?

The `salience_after_feedback` function applies an immediate scalar adjustment based on the feedback variant. For example, `FeedbackKind::Helpful` adds a positive offset to the current salience before the next decay cycle, effectively resetting the forgetting curve for that observation.

### Where is the decay logic located in the source code?

The core formula resides in [`crates/ai-memory-store/src/decay.rs`](https://github.com/akitaonrails/ai-memory/blob/main/crates/ai-memory-store/src/decay.rs). Candidate retrieval lives in [`crates/ai-memory-store/src/reader.rs`](https://github.com/akitaonrails/ai-memory/blob/main/crates/ai-memory-store/src/reader.rs), soft-delete operations are in [`crates/ai-memory-store/src/ops.rs`](https://github.com/akitaonrails/ai-memory/blob/main/crates/ai-memory-store/src/ops.rs), and the high-level sweep orchestration appears in [`crates/ai-memory-wiki/src/wiki.rs`](https://github.com/akitaonrails/ai-memory/blob/main/crates/ai-memory-wiki/src/wiki.rs). Design rationale is documented in [`docs/design-decisions.md`](https://github.com/akitaonrails/ai-memory/blob/main/docs/design-decisions.md).

### What prevents important pages from being deleted?

Any page marked with `pinned = true` is automatically excluded from the `decay_candidates` query. Additionally, pages receiving regular positive feedback maintain higher salience scores that stay above the `salience_threshold`, preventing soft-deletion during sweeps.