Agent memory: three tiers, plain markdown, no database
Table of Contents
Agents without memory are a demo. You brief them, they do the thing, and the next session starts from nothing.
Memory is what turns that into a system. It is also the part that most often degrades, because writing to memory feels productive and pruning it never does. Six months in, the agent is reading four thousand lines of stale notes to answer a question it could have answered from three.
Use the filesystem
The instinct is to reach for a vector database. For most agent systems that is the wrong tool, and it is worth being clear about why.
Retrieval quality is not usually the bottleneck. Knowing what is true is the bottleneck. When an agent acts on something wrong, you need to open the memory, read it as a human, see the wrong line, and fix it. A folder of markdown in git gives you that: greppable, diffable, reviewable in a pull request, restorable to any point in time.
An embedding store gives you fuzzy recall and almost no ability to audit. You can inspect what came back for a query; you cannot easily read the whole corpus and spot the contradiction.
Use vectors when the corpus is genuinely large and genuinely unstructured - thousands of support tickets, a document archive. For an operating system’s own memory, measured in hundreds of facts, plain files win on every axis that matters.
The three tiers
The split that holds up is by lifespan, not by topic. Topic-based folders feel tidy and tell you nothing about what to prune.
Tier 1 - durable facts
Things true until explicitly changed. Pricing. Architecture decisions. Who owns what. Brand rules. Constraints that bind.
One fact per file, with a short description in frontmatter so it can be found without opening it. Cross-link related facts. This tier is small and should stay small: if it exceeds a few hundred entries, most of it is not actually durable.
Critically, corrections overwrite here. When pricing changes you edit the pricing file. You do not append “update: pricing is now X” underneath the old number, because the next reader gets both and has to guess.
Tier 2 - the daily log
Append-only, dated, never edited. What happened, what shipped, what broke, what was decided. This is the audit trail, and its value is entirely in being untouched - the moment you start tidying it, it stops being evidence.
Recent entries load; older ones are archived and searched on demand. A rolling window of about a week covers nearly every “what did we just do” question.
Tier 3 - working state
The current task. Scratch notes, intermediate results, the half-finished plan. Deliberately disposable, cleared between tasks.
The failure mode here is letting tier 3 leak into tier 1. Something learned while debugging feels durable in the moment and is usually specific to that bug. The filter: would this still be true in six months, and would someone need it? If not, it belongs in the log or nowhere.
Write the why, not the what
Memory that records decisions without reasons ages badly. “We use Neon” tells a future reader nothing about whether the decision still holds.
“We use Neon because database branching lets each environment get a real database, and migrations are tested against production-shaped data before they ship” can be re-evaluated. When the reason stops being true, the decision is visibly up for review.
Load selectively
Everything in memory competes for context. The pattern that scales is an index that is always loaded, and content that is loaded on demand.
The index is one line per fact - name and a description good enough to decide relevance. The agent reads the index every session, and opens only what the current task needs. A hundred facts cost a hundred lines of context instead of several thousand.
Prune on a schedule
Memory rot is the default. Nothing about normal operation removes anything, so entropy only goes one way.
Run a scheduled pass that reads memory and proposes deletions and merges - duplicates, superseded facts, notes that turned out to be task-specific. Proposes, not performs: an agent that can silently delete its own memory can silently delete something load-bearing.
What to read next
- The filesystem is my database - the longer argument, with the failure modes.
- Claude Code orchestration - how memory gets read and written during real work.
- Designing an MCP server - the tool surface that writes to this memory.