I Tried to Make Claude “Remember” for Six Months. Then I Built It a Memory.
Six months of telling Claude to remember produced zero accumulated knowledge, because the medium doesn’t persist — files on disk, indexed, do.
The third time I had to correct the same drift, I realized something embarrassing: none of my previous “remember this for next time” instructions had survived.
Not one.
Six months of telling Claude “remember our convention is X.” Every session opened cold. Every correction landed in the same place the previous one had landed. None of them carried forward.
The mistake wasn’t the corrections. The mistake was thinking “remember” was a feature instead of a system I had to build.
Why prompt-only memory fails
A Claude session has no persistent state by default. The model doesn’t carry knowledge between sessions; “remember this” lives as long as the current conversation, then disappears with it.
The conversation summary that survives compaction is lossy on purpose. It captures the shape of the work, not the load-bearing one-liner you said an hour in. The line you most need to survive — the rule you just discovered the hard way — is the one most likely to be summarized away.
Six months of “remember X” produces zero accumulated knowledge because the medium doesn’t persist. No amount of clarity in the instruction will fix that. What works is a different medium: files on disk that the next session reads at startup.
File-based memory as a system, not a feature
The architecture I landed on is small and unglamorous: a memory/ folder scoped by role. The orchestrator has its own subfolder; each worker that needs persistent context has its own. One Markdown file per memory entry. Frontmatter on top with name, description, type. Body underneath with the actual content. A flat MEMORY.md index at the top of the folder. One line per memory file. Loaded automatically every session.
That’s the whole shape. No database. No vector store. No clever retrieval. Just files, indexed by a one-liner, scoped to the worker that needs them.
The reason this works: Claude reads MEMORY.md at the start of every session in that role. The index tells it what exists. If the current task makes a specific entry relevant, Claude opens that one file and pulls the content. The full memory surface stays on disk; only the index and the entries actually needed are in context.
The goal isn’t to load everything you ever taught Claude into every session. The goal is to load the one-line summary of everything, and the full body of only what’s relevant right now.
The four memory types
Saving everything as “miscellaneous notes” doesn’t work either. After thirty entries, nothing is findable, and Claude can’t tell which are still load-bearing. The taxonomy I use has four types.
user — who the user is, their role, preferences, technical background, what they’re trying to accomplish at a higher level than any single task. Saved once and updated rarely. “User is a senior backend engineer working on a Go service. Prefers terse code-first responses. New to React.”
feedback — guidance the user has given me about how to work. Both corrections (“stop doing X”) and validated approaches (“the bundled-PR call was right”). This is the type I save most often, because every correction is a memory candidate. Every feedback entry includes a Why: line (the reason the user gave) and a How to apply: line (when this rule kicks in). Without the why, future-me can’t judge edge cases.
project — the state of ongoing work. Deadlines, active decisions, who’s blocking what. This type decays the fastest — a project memory from three months ago is almost always stale or already shipped. The discipline here is regular pruning, not aggressive saving.
reference — pointers to where information lives in external systems. “Pipeline bugs are tracked in Linear project INGEST.” “The latency dashboard at grafana.internal/d/api is what oncall watches.” Tiny entries, high value. They tell future-me where to look without trying to mirror the content.
Every saved memory belongs to exactly one type. If it could belong to two, it’s probably two memories.
The file shape
A generic memory file has frontmatter on top — name (a short kebab-case slug), description (one-line summary used to decide relevance in future conversations), metadata with a type of user, feedback, project, or reference — and a body underneath. For feedback and project types, the body is structured as a rule or fact, then a Why: line and a How to apply: line.
The description is the single most important field. That one line is what appears in the index. It’s what future-Claude reads to decide whether the entry is worth opening. A vague description (“notes about testing”) makes the entry effectively invisible; a specific one (“integration tests must hit a real DB — prior incident where mocks masked a broken migration”) makes it findable when the relevant moment arrives.
What NOT to save (the discipline that matters)
This is where most memory systems fail. They save too much. The signal-to-noise ratio collapses, the index bloats past usefulness, and the next session ignores all of it.
Things that look like good memory candidates but aren’t: code patterns or conventions derivable from the current files (naming, structure, architecture — all of this is in the code; save a memory about it and you create a second source of truth that will drift); git history (git log is authoritative — a memory entry summarizing what happened in the last sprint is stale within a week); debugging fix recipes (the fix is in the code, the commit message has the context — a memory entry duplicating both is a third copy that will rot); anything already in CLAUDE.md or project docs (if it’s in the always-loaded surface, it doesn’t need to be in memory too); ephemeral task state (“currently working on the auth refactor” belongs in a todo list, not in long-term memory).
If a memory entry could be replaced by grep or git log or “just read the file,” it shouldn’t exist. Memory is for things that can’t be reconstructed from current state: a past incident, a preference, a person, a decision and its reasoning.
The discipline I apply: before saving, ask whether the content will still be true and useful in three months. If not, it’s task state, not memory.
Markers — your memory is leaking or stale
A few tells that mean the system needs a sweep.
Your MEMORY.md index has grown past two hundred lines. It’s truncating before Claude reads the bottom entries. Prune or re-scope.
Memory entries reference files that have been renamed or deleted. The memory is now lying. Delete or update the moment you notice.
Two memory entries contradict each other. One of them is stale. You have to pick.
You catch yourself re-checking the current code to confirm what a memory says. That memory has lost trust — either fix it or remove it. A memory you don’t trust is worse than no memory, because it slows down decisions while pretending to speed them up.
The system requires maintenance. Weekly pruning is cheap; six-month neglect produces an index nobody can trust.
What I’m giving you, and what I’m not
You have the architecture: the folder shape (one file per memory plus flat index, scoped by role).
The four types and what each is for.
The frontmatter shape and the Why: / How to apply: body convention for feedback and project entries.
The “what not to save” discipline.
The four markers for when the system needs maintenance.
What I’m not giving you: my actual memory entries. Not because they’re secret — because they’re shaped to my work, my workers, my mistakes. If I hand you my user-memory file, you’ll spend two weeks reverse-engineering my preferences instead of two days noticing your own. The taxonomy travels. The contents don’t.
The taxonomy is what matters. Build the system, let your sessions fill it, prune ruthlessly. By month three you’ll have a memory surface that does in 50 lines what six months of “remember this” never did.