Three tiers, mirroring how brains remember.

Memories don't all live forever. Working notes expire in hours. Project context survives a week. Durable knowledge stays until you say otherwise. ai-memory's Short / Mid / Long tier system mirrors human working / episodic / long-term memory and lets agents forget noise without losing what matters.

3 tiers auto-TTL ladder governance-gated promotion since v0.1
The three tiers

Short, Mid, Long.

Every memory carries a tier. The default is Mid — the sweet spot for most session-spanning facts. Short is for ephemeral working memory that should age out fast. Long is for durable knowledge that should never auto-expire. Choose explicitly on write, or let the default carry you.

Short
default TTL · 6 hours
Working memory. Notes from right now. Things you'd lose if you slept on them. Auto-expires unless explicitly extended. Use for: call logs, transient observations, "remind me at 3pm," intermediate reasoning steps.
TTL6 × 3600s
Extend+1h on access
Expires?yes
Tier rank0
Mid
default TTL · 7 days
Episodic memory. Project context. The default tier. A week is enough for a sprint, a deal cycle, or a research thread. Auto-expires unless promoted to Long. Use for: sprint goals, customer notes, debugging sessions, draft decisions.
TTL7 × 86400s
Extend+1d on access
Expires?yes
Tier rank1
Long
no TTL · durable
Long-term memory. Durable knowledge. Architectural decisions. Standards. Things that shape future behavior. Promotion to Long passes through governance — only the right callers can persist forever. Use for: charters, post-mortems, contracts, golden patterns.
TTLnone
ExtendN/A
Expires?no
Tier rank2
The TTL ladder

From hours to days to forever — three slopes.

Each tier has its own decay slope. Short bleeds out in hours. Mid in days. Long holds. Access bumps the expiry forward by a tier-specific extend interval, so memories that matter get used and earn more time.

100% 50% 0% retained store +1h +6h +1d +7d +30d elapsed time (log scale) Short — TTL 6h Mid — TTL 7d Long — no TTL expires expires durable

The slopes are illustrative — the actual retention curve is binary in v0.6.3 (memory either exists past TTL or has been GC'd / archived). v0.7+ may add probabilistic decay if telemetry shows operators want it.

Biological mirror

Modeled on human memory architecture.

The Short / Mid / Long division isn't arbitrary — it borrows the cognitive-psychology distinction between working memory (seconds-minutes), episodic memory (hours-days, recent context), and long-term memory (durable knowledge that survives consolidation). AI agents that reason like humans benefit from a memory system that ages like one.

Human memory

  • Working memory — seconds to minutes. Phone numbers held briefly. Lost without rehearsal.
  • Short-term store — minutes to hours. Today's errands. Bedtime erases most of it.
  • Episodic memory — days to weeks. Last week's meetings. Subject to rehearsal-driven consolidation.
  • Long-term memory — years to lifetime. Childhood. Skills. Identity-shaping events.
  • Consolidation — sleep + repetition turn episodic → long-term.

ai-memory

  • (none) — sub-second working state lives in agent context, not ai-memory.
  • Short tier — 6h default. Working notes from "right now." Auto-expires.
  • Mid tier — 7d default. Project / sprint / session context. Auto-expires unless promoted.
  • Long tier — no TTL. Promoted memories. Durable.
  • memory_consolidate — bulk-collapses N memories into 1 derived summary (LLM, smart-tier+).
Promotion path

Mid → Long, the only edit that affects retention.

A memory's tier can change. The most important transition is Mid → Long — the moment something stops being session context and starts being durable knowledge. ai-memory routes promotion through governance, so the right caller (or the right approver) decides what lives forever.

step 1
Caller submits
memory_promote with the target id. The daemon resolves the memory's namespace.
step 2
Governance check
Pick policy.promote from the namespace standard. Default Any. Other levels: Registered, Owner, Approve.
step 3
Verdict
Allow → promote. Deny(reason) → reject with the reason. Pending(id) → queue for approval, return 202.
step 4
Tier flip
Tier set to long. expires_at cleared. Federation fanout via quorum write.

Tier-downgrade refused at SQL. The schema's tier_rank() function and a GREATEST(tier_rank(...)) precedence rule (Postgres + SQLite) refuse Long → * and Mid → Short at the storage layer. The HTTP / MCP path can't accidentally regress a memory's durability through a malformed update.

Knobs you actually use

Override the defaults when you need to.

Tier defaults cover most cases. When they don't, every dimension is a knob you can override per memory or per namespace.

On write — the per-memory knobs

// MCP — memory_store { "title": "Q3 OKR review notes", "content": "…", "tier": "mid", // or "short" / "long" "ttl_secs": 86400, // override default tier TTL: 1 day instead of 7 "expires_at": "2026-12-31T23:59:59Z", // or set explicit expiry "priority": 8 // 1-10 — drives recall ranking }

In daemon config — change the tier defaults

# config.toml [ttl] short_ttl_secs = 3600 # 1h instead of 6h mid_ttl_secs = 2592000 # 30d instead of 7d long_ttl_secs = 0 # 0 = no TTL (default for Long) short_extend_secs = 1800 # bump expiry 30min on access mid_extend_secs = 86400 # bump 1d on access

Per-namespace governance — gate the promotion

// namespace standard's metadata.governance { "write": "any", "promote": "approve", // every Long-tier promote needs approval "delete": "owner", "approver": {"consensus": 2} // 2 votes from registered agents }
What expires + when

Garbage collection — automatic, observable.

When a memory's expires_at passes, GC sweeps it on the next cycle. Two paths: hard delete, or archive-on-GC (configurable). Archived memories are restorable; deleted ones are not. Default is archive — recoverable by design.

cycle
memory_gc tick
Periodic sweep. Walks memories WHERE expires_at < now(). Default cadence configurable; can also be invoked on-demand via the MCP memory_gc tool.
option A
archive_on_gc=true (default)
Row moves to archived_memories with full metadata. Restorable via memory_archive_restore. Purge-able via memory_archive_purge when you really want it gone.
option B
archive_on_gc=false
Hard delete. Row removed from memories. FTS index updated. HNSW vector evicted. Federation fanout deletes peer copies.
forever
Long tier untouched
No expires_at means GC's WHERE clause never matches. Long memories survive every sweep until something else (delete, forget, archive) touches them.

Forget vs. delete. memory_forget is a pattern-based bulk operation — same effect as GC's archive path but on demand. memory_delete is per-id and goes through governance. Either way the federation fanout keeps peers consistent.

Why this matters

Tiering is the only thing that lets agents scale.

Without tiers — every observation is permanent. After a week of agent activity you have a million rows, recall returns noise, and storage budget is your bottleneck.
With tiers — most memories age out in days. Recall stays sharp because the candidate set is bounded. Operators promote to Long the things that matter — those become the durable substrate. The system works the way real cognition works.
Audit-friendly — promotion is a governance-gated event. Every "this stays forever" decision has a paper trail in pending_actions if the policy required approval, or a stamped updated_at on the row.
Compliance-ready — TTL is a structural retention control. "We expire ephemeral notes within 24 hours" stops being a process claim and becomes an enforced default at the storage layer.