← All Claude Code tips
02

Giving Claude a Memory That Outlives the Session

Context windows end. Projects do not. Why I keep my AI's long-term memory in an Obsidian vault instead of a config file, and the rules that decide what gets written.

Foundations8 min read· Updated 8 Aug 2026

Every session starts from zero.

You spend forty minutes working out why a client's staging environment rejects webhook callbacks. You fix it. The session ends. Three weeks later the same thing happens on a sister site, and you are back at the beginning — because the reasoning lived in a context window that no longer exists.

The previous part covered rules, which are static. This is the other half: facts, which accumulate.

Why not just put it in CLAUDE.md

The obvious move is to append findings to CLAUDE.md. It works for about two weeks.

The file grows. It gets loaded in full at the start of every session, so a fact you needed once in March is now costing you tokens in December. There is no structure — a gotcha about WooCommerce webhooks sits next to a note about your preferred date format. And because it is one file across one project, nothing connects. The webhook fix you made for client A is invisible when you hit the same issue for client B.

What you want is closer to a wiki: many small notes, each about one thing, retrieved on relevance rather than loaded wholesale, and linked to each other.

That is what Obsidian already is. So I use it.

The shape of the vault

Four top-level folders, each with a different job.

Projects/<project-name>/
  index.md
  Conversations/
    2026-08-04-webhook-signature-mismatch.md
Preferences/
Architecture/
Tags/
  tag-taxonomy.md

Projects/ holds one folder per codebase. The index.md is the living summary — tech stack, patterns, gotchas, key decisions. Conversations/ holds dated notes from individual sessions, which is where the "how we solved that weird thing" material goes.

Preferences/ is global and stack-agnostic: how I like things done, independent of project. Architecture/ holds decision records — the ones you would otherwise write as an ADR and then never write.

The split matters because it maps to retrieval. When starting work on a repo, the project note is what you want. When making a technology choice, Architecture/ is what you want. Separate folders make "read the relevant thing" a cheap operation instead of a search.

The rule that makes it work

Here is the part that took longest to get right, and it is one line:

Do NOT ask "should I save this to memory?" — just do it silently
alongside your normal response.

Memory systems fail because writing to them is friction. If the assistant asks permission every time, you say no — you are mid-task, the interruption costs more than the note is worth. Ask ten times, get ten noes, and the vault stays empty.

Making writes silent and automatic inverts it. The cost of a slightly redundant note is near zero. The cost of a lost insight is another forty minutes three weeks from now. Bias hard toward writing.

The same logic drives the read side:

- At the START of every session: read the relevant
  Projects/<project-name>/index.md for the current working directory.
- Before making architecture or tech decisions: check Architecture/
  and the project note for prior decisions.

Automatic, tied to a trigger, no asking.

What actually gets written

Silent writing only works if the triggers are specific. "Save important things" produces either nothing or everything. Mine is a list of events:

  1. Bug fixed → append to the project note's Gotchas, or a dated conversation note
  2. Architecture or tech decision made → update the project note and create an Architecture/ record
  3. New dependency added or stack changed → update the project note's Tech Stack
  4. A preference stated ("I prefer X over Y") → Preferences/
  5. Pattern established (convention, folder structure, naming) → project note's Patterns
  6. Non-obvious problem solved → dated conversation note with the solution
  7. New project encountered → full project note from the template
  8. End of a meaningful session → summary note

Every one of those is an observable event, not a judgement call. "Was a bug fixed?" has an answer. "Was this important?" does not.

Number 6 is the one that pays for the whole system. Non-obvious problems are exactly the ones you will not re-derive quickly, and exactly the ones you forget you ever solved.

Linking, or it is just a folder of files

Notes that do not link are a directory listing with extra steps. Two rules force the graph to form:

- Always use [[wiki links]] to connect related notes
- Every note should link to at least one other note — no orphan nodes
- Add a ## Related section at the bottom of each note

The "no orphans" rule is doing real work. It forces a question at write time: what is this related to? Answering it is how you notice that the webhook problem on client A is the same class of problem as the one on client B — because you are looking for something to link to.

Tags do the cross-cutting version. A small controlled taxonomy, defined once in Tags/tag-taxonomy.md, rather than free-form tagging that fragments into #bugfix, #bug-fix and #bugFix:

Core:   #decision #pattern #bug-fix #preference #gotcha #til
Status: #active #archived #revisit
Scope:  #project #global #session

Three axes, closed vocabulary. #revisit is the sleeper — it marks decisions made under time pressure that deserve a second look, which is otherwise a thought that evaporates the moment you ship.

How it connects

Obsidian exposes the vault over MCP, so the tools show up like any other. Read, write, patch, search, manage tags, resolve wiki links. Nothing bespoke — the assistant is just editing Markdown files in a folder.

That is the property I care about most. The memory is not locked inside a tool. It is plain Markdown on disk. I can read it in Obsidian, grep it from a terminal, commit it to git, or open it in any editor in twenty years. If I stop using Claude Code tomorrow, I keep everything.

Compare that to memory features built into a product, where your accumulated project knowledge lives in someone else's database in a format you cannot inspect. For notes about client systems I am contractually responsible for, that is not a trade I will make.

What it does not solve

Three honest limits.

Notes go stale. A note saying "auth lives in server/api/auth.ts" is wrong the moment you move the file, and nothing tells you. Anything memory says about code structure needs verifying against the repo before you act on it. Treat memory as a hypothesis, not a fact.

Retrieval is imperfect. Notes surface by relevance matching against their descriptions, so a badly-described note is invisible no matter how good its contents. Write the summary line for the search, not for yourself.

It can be confidently wrong. A note recording a decision records what was true when it was written. If you reversed that decision six months later and did not update the note, the old reasoning gets applied to new work. The #revisit tag and periodic review are the only real defence.

None of these are reasons not to do it. They are reasons to keep it in a format you can audit — which is, again, the argument for plain Markdown.

Start smaller than this

If the full structure looks like a lot, it is — it accreted over dozens of projects and did not start here.

Start with one folder and one rule: after solving something non-obvious, write a dated note with the problem and the solution. That is it. No taxonomy, no linking, no templates.

Do that for a month. The structure will suggest itself, because you will get annoyed at not being able to find things — and every folder above exists because of exactly that annoyance.


Next: the four ways to extend Claude Code — skills, agents, commands and plugins — and how to tell which one a problem actually needs.

// ready?

Need a developer who ships fastwithout shipping mess?

I build and maintain WordPress, Laravel and Nuxt applications for businesses that care about performance and maintainability.