# How ai-memory Implements Its Memory Tier Decay Model: A Technical Deep Dive

> Discover how ai-memory implements its memory tier decay model. Explore the deterministic mathematical function using exponential decay and logarithmic reinforcement for retention scores. Learn more.

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

---

**ai-memory implements its memory tier decay model as a deterministic mathematical function that converts page metadata—age, access frequency, salience, and operator breadth—into a retention score using exponential decay curves and logarithmic reinforcement, storing tunable parameters in the `DecayParams` struct and calculating scores via `retention_score` and `retention_score_with_breadth` functions in [`crates/ai-memory-store/src/decay.rs`](https://github.com/akitaonrails/ai-memory/blob/main/crates/ai-memory-store/src/decay.rs).**

The ai-memory project provides a SQLite-backed memory system for AI applications that automatically manages data lifecycle through a sophisticated decay mechanism. Unlike simple LRU caches, this memory tier decay model balances aging data against access patterns and multi-user engagement to determine which pages remain in hot storage, move to cold tiers, or face permanent deletion.

## Core Decay Parameters in `DecayParams`

The decay behavior is governed by the **`DecayParams`** struct defined in [`crates/ai-memory-store/src/decay.rs`](https://github.com/akitaonrails/ai-memory/blob/main/crates/ai-memory-store/src/decay.rs). These coefficients shape the retention curve and determine how aggressively the system forgets information:

- **`lambda`** – Controls the exponential decay of page age with a default value of approximately `0.02`, creating roughly a 35-day half-life for aging content.
- **`sigma`** – Sets the magnitude of access-based reinforcement, determining how much repeated access can counteract age decay.
- **`mu`** – Applies additional exponential decay based on days since last access, ensuring stale pages fade even if they were once popular.
- **`salience_default`** – Provides a fallback salience value when users have not explicitly rated a page's importance.
- **`cold_threshold`** – The score boundary below which pages become candidates for eviction to cold storage.
- **`hard_delete_after_days`** – Defines the tombstone period; after eviction, records persist for this duration before permanent removal.

## Calculating Retention Scores

The model computes retention through two related functions that transform raw metadata into a single floating-point score. Higher scores indicate stronger retention priority.

### Base Retention Score Function

The `retention_score` function serves as the primary interface for single-user scenarios. According to the source in [`decay.rs`](https://github.com/akitaonrails/ai-memory/blob/main/decay.rs) (lines 66-74), this function delegates to the broader implementation while preserving historical behavior by passing zero values for breadth parameters:

```rust
use ai_memory_store::decay::{DecayParams, retention_score};

// Use the default parameters (λ≈0.02, σ=0.6, μ=0.04, …)
let params = DecayParams::default();

// Example page metadata
let age_days = 45.0;           // 45 days since last update
let access_count = 12;        // 12 total hits
let days_since_access = Some(3.0);
let salience = Some(0.8);     // user-provided salience

let score = retention_score(
    &params,
    age_days,
    access_count,
    days_since_access,
    salience,
);
println!("Retention score = {}", score);

```

### Breadth-Weighted Scoring for Multi-User Access

The `retention_score_with_breadth` function extends the model to account for **operator breadth**—how many distinct actors have accessed a page. This prevents idiosyncratic personal data from persisting while reinforcing communally relevant information. The implementation (starting at line 94) adds a logarithmic breadth term weighted by `breadth_weight`:

```rust
use ai_memory_store::decay::{DecayParams, retention_score_with_breadth};

let params = DecayParams::default();
let score = retention_score_with_breadth(
    &params,
    30.0,               // age_days
    5,                  // access_count
    Some(1.0),          // days_since_access
    None,               // salience → falls back to default
    4,                  // distinct_actors
    0.5,                // breadth_weight – give extra credit for multiple users
);
println!("Score with breadth = {}", score);

```

When `breadth_weight` is set to `0.0`, the function reverts to the legacy single-user formula.

## The Mathematical Model Behind Tier Transitions

The retention score derives from four interacting components defined in [`crates/ai-memory-store/src/decay.rs`](https://github.com/akitaonrails/ai-memory/blob/main/crates/ai-memory-store/src/decay.rs) (lines 48-89). The system combines these terms to produce the final retrievability metric:

1. **Age Decay** – Exponential decay of the page's lifetime: `(lambda * age_days).exp()`
2. **Access Reinforcement** – Logarithmic scaling of access count multiplied by recency decay: `sigma * ln(1 + access_count) * (mu * days_since_access).exp()`
3. **Operator Breadth** – Logarithmic bonus for multi-user relevance: `breadth_weight * ln(distinct_actors)`
4. **Salience Modulation** – Direct importance weighting divided by the age component

The simplified formula produces higher scores for pages that are fresh, frequently accessed, broadly relevant, and explicitly marked as salient.

## Cold Tier Eviction and Hard Deletion

The decay model directly drives storage tier transitions through two threshold-based mechanisms:

- **Eviction Candidates** – Pages with scores below `cold_threshold` become candidates for moving from hot to cold storage during the background forget-sweep job.
- **Tombstone Lifecycle** – After eviction, records enter a tombstone state where they persist for `hard_delete_after_days` before the system executes permanent deletion.

This deterministic approach ensures that storage cleanup requires no manual intervention while providing predictable data retention windows.

## Database Schema Support

The decay model relies on specific SQLite schema elements added through migration files. The [`V03__decay.sql`](https://github.com/akitaonrails/ai-memory/blob/main/V03__decay.sql) migration introduces the columns required for score calculation—including `access_count`, `last_accessed_at`, and `salience`—while [`V49__decay_tombstone_index.sql`](https://github.com/akitaonrails/ai-memory/blob/main/V49__decay_tombstone_index.sql) creates indexes for efficient lookup of records eligible for hard deletion.

## Summary

- The **`DecayParams`** struct in [`crates/ai-memory-store/src/decay.rs`](https://github.com/akitaonrails/ai-memory/blob/main/crates/ai-memory-store/src/decay.rs) centralizes all tunable coefficients for the decay curve.
- Two scoring functions—`retention_score` and `retention_score_with_breadth`—handle single-user and multi-user retention calculations.
- The formula combines exponential age decay, logarithmic access reinforcement, and explicit salience values into a deterministic retention metric.
- The **`cold_threshold`** and **`hard_delete_after_days`** parameters govern automatic tier transitions and permanent deletion.
- SQLite migrations store the metadata columns and indexes required to support the computational model at scale.

## Frequently Asked Questions

### What is the mathematical formula for the retention score in ai-memory?

The retention score combines four logarithmic and exponential terms: age decay calculated as `(lambda * age_days).exp()`, access reinforcement as `sigma * ln(1 + access_count) * (mu * days_since_access).exp()`, a breadth modifier as `breadth_weight * ln(distinct_actors)`, and a salience term divided by the age component. These are summed to produce a single floating-point value where higher numbers indicate stronger retention priority.

### How does ai-memory handle multi-user access patterns in its decay model?

The system uses the `retention_score_with_breadth` function to incorporate **operator breadth**, adding a weighted logarithmic bonus based on the number of distinct actors who have accessed a page. This ensures that data touched by multiple users receives additional retention priority over personally relevant but isolated information.

### What triggers a page to move from hot to cold storage?

Pages automatically become eviction candidates when their computed retention score falls below the `cold_threshold` value defined in `DecayParams`. A background forget-sweep job periodically recomputes scores for all stored pages and moves those below the threshold to cold tiers without manual intervention.

### How long does ai-memory keep deleted page records before permanent removal?

After a page is evicted to cold storage, it enters a tombstone state that persists for the duration specified by `hard_delete_after_days` (typically configured in `DecayParams`). Once this period expires, the system permanently removes the row from the SQLite database.