Skip to content

Decay and recency

Old memories should not crowd out current ones, but some memories never stop mattering. Meaning Memory lets age count in two separate places, and each has its own setting:

Search ranking Compiled memory file
What ages Every memory’s weight in search results Which memories survive the file’s size budget
On by default Yes No
Setting MM_S1_HALF_LIFE_DAYS (90 days) MM_DECAY_ENABLED plus a decay_policy preset
Stored significance changes? No No

Neither one changes the significance stored on a memory. Age is applied when ranking, so turning decay off again restores the previous behaviour completely.

Search ranks results by how well they match, their significance and their age together. A memory’s weight halves for every 90 days since it was written, so an old memory has to match better or matter more to rank as high as a new one. The weight never reaches zero, but it falls fast: at equal match, a two-year-old memory at significance 0.95 ranks below yesterday’s memory at 0.10. Pin memories that must stay easy to find, or use a longer half-life.

Change the period with MM_S1_HALF_LIFE_DAYS in the environment of the MCP or REST server; a longer half-life favours older memories.

The compiled memory file has a size budget. With decay on, a memory counts for less in that budget as it ages, so old, low-value memories give way to newer ones. It is off by default.

Turn it on with two settings where consolidation runs. In the workspace’s mm-base.toml:

[decay]
decay_policy = "conservative"

and in the consolidation command’s environment:

Terminal window
MM_DECAY_ENABLED=true MM_BACKEND=file meaning-memory consolidate --agent-id support-bot \
--drain-only --workspace /srv/support-bot-mm --config-dir /srv/support-bot-mm

An unknown preset stops the run with an error listing the valid ones, so a typo can’t silently turn decay off.

The half-life is the age at which a memory counts for half as much. With none, nothing decays except memories that carry their own curve (see below).

Category none (default) conservative (recommended) aggressive
episode, relational never 180 days 180 days
content, preference never 365 days 180 days
fact never never 180 days
commitment, identity never never never
deadline never after its date after its date
any other category never 365 days 180 days

A deadline steps down only if the memory carries its own date (its when field), which deadlines extracted from notes during consolidation have. mm_remember and the REST API don’t set one, so deadlines written that way keep their significance.

Decay is applied when the compiled file is rebuilt (see When it is rebuilt), so a change of preset shows at the next rebuild, not at the next drain on its own.

Choose conservative unless the compiled file is under real pressure from old material; aggressive lets facts fade too. Commitments never decay under any preset; they stay on the due list until they are closed (see Commitments).

Two kinds of memory stay in the compiled file whatever their age:

  • Pinned memories: pinned with mm_feedback and pin, or stored pinned (a memory written with significance 0.90 or above is).
  • Memories with their own decay_curve of none, which don’t decay at all.

Protection that comes only from a high significance score, without the pin, is checked against the decayed score, so it can lapse with age. If a memory should never drop out, pin it.

A memory’s own decay curve can be set when it is loaded in bulk, with mm_bulk_remember (per memory, or for the whole batch with default_decay_curve) or meaning-memory seed --default-decay-curve. Bulk loads default to none, so seeded knowledge doesn’t fade unless you say so. The accepted curves are none, step and exponential. mm_remember and the REST API don’t take a curve; their memories follow the preset for their category.