How Claude Code remembers
TL;DR
When you correct Claude, it writes a note to a folder of Markdown files for that project. Only an index of those notes is loaded into every conversation. Read the folder now and then, and delete what’s wrong.
How it works
Two kinds of memory
Claude has two kinds of memory, and both are loaded at the start of every conversation:
CLAUDE.md: instructions you write yourself and commit with the code. Keep it as close to empty as you can.- Auto memory: notes Claude writes itself when you correct it or tell it something worth keeping.
The memory folder
Auto memory is a folder of plain Markdown files on your machine, one folder per project: an index, plus one small file per memory.
The folder starts empty, and there’s no fixed list of files. Claude creates them from what you tell it, and picks the names itself. Tell it “always use UTC as the timezone” and it creates something like feedback_utc_timezone.md, plus a line for it in the index. After a few weeks, a folder could look like this:
~/.claude/projects/<project>/memory/
├── MEMORY.md # the index: one line per memory
├── feedback_utc_timezone.md # from "always use UTC as the timezone"
├── feedback_constructor_injection.md # from "use constructor injection, not @Autowired fields"
├── project_translations.md # from "translations live in a Google Sheet, ask me to edit it"
└── project_release_freeze.md # from "no merges to main until the release on the 20th"
Only the index is loaded into every conversation. Claude opens a memory file when its line in the index looks relevant to what it’s doing. When you correct it again on the same subject, it updates that file instead of adding a new one.
/memory opens the folder, and you can edit or delete anything in it.
My take
- Read its memory now and then. It’s a handful of Markdown files. Delete what’s wrong or outdated.
- Give a reason with every correction. “Don’t do X, because Y.” The reason ends up in the memory, and lets Claude apply the rule to cases you didn’t mention.
Gotchas
- An outdated memory keeps steering. “No merges until the release on the 20th” is still followed in December, until you delete it.
- Your memory isn’t your colleagues’. The folder lives on your machine. A rule the whole team needs belongs in the code, a linter or a test, where everyone gets it.
Example
Claude adds a new label to messages_nl.properties. But the translations are managed in a Google Sheet, and the file is overwritten every time they’re pulled in. Tell it once:
“Translations are managed in a Google Sheet, not in the properties files. When you need a new or changed translation, ask me to make the edit in the sheet, then pull them in with ./gradlew pullTranslations. Remember that.”
That ends up as a line in the index:
- [Translations](project_translations.md) — translations live in a Google Sheet; ask me to edit it, then run ./gradlew pullTranslations
and a file of its own, project_translations.md:
---
name: translations
description: Translations are managed in a Google Sheet, not in the properties files
type: project
---
Translations are managed in a Google Sheet. The `messages_*.properties` files are overwritten
every time they're pulled in, so don't edit them.
When a translation is new or changes, ask the user to make the edit in the sheet,
then run `./gradlew pullTranslations`.
**Why:** the sheet is the source of truth; edits to the properties files are lost on the next pull.
Every later conversation in this project sees the index line, and opens the file when it’s about to touch a translation.