I gave Claude 12,732 memories. Here's what it noticed.
I put the memory system together, used it for a couple months, and then stopped to look at what it had actually accumulated.
The previous post
describes how the three layers work: CLAUDE.md for static context, MemPalace
for dynamic session memory, a knowledge graph for structured facts. MemPalace is not Claude’s built-in memory feature — it’s infrastructure I run myself, with memories stored in ChromaDB and SQLite on my machine and integration over MCP (Model Context Protocol), an open standard any compatible client can speak. If I swapped models tomorrow, everything it has accumulated would stay put.
The terms below come from MemPalace’s own structure: a wing is one per project (plus a shared one for cross-project sessions), a room is a topic inside a wing (technical, architecture, problems, and so on), and a drawer is a single stored memory. This post is the other side of the design — what’s actually in it after months of real use, and what that reveals about how I work in my projects.
The palace, in numbers
The first time I ran this autopsy, the palace held 2,388 drawers across 8 wings. I’m rerunning it now, weeks later — and in between, a hackathon spun up new projects and left long sessions behind for the hooks to mine. The numbers moved more than I expected.
12,732 drawers total across 13 wings.
Wings by drawer count:
| Wing | Drawers |
|---|---|
sessions (cross-project) | 12,478 |
wing_personal_blog | 56 |
wing_geo_service | 51 |
wing_projects | 44 |
wing_video_pipeline | 34 |
wing_devops_toolkit | 24 |
wing_content_studio | 17 |
wing_rural_registry | 12 |
wing_ci_templates | 5 |
wing_theme_engine | 3 |
wing_vision_experiment | 3 |
wing_windows | 3 |
wing_config_service | 2 |
Content by room type, across all wings:
| Room | Drawers |
|---|---|
technical | 10,893 |
architecture | 861 |
general | 357 |
planning | 321 |
diary | 251 |
problems | 46 |
disk | 3 |
The first thing I noticed: architecture (861) still dwarfs problems (46) — about 19 to 1. Smaller gap than the 114-to-1 I found the first time around, but the shape of the conclusion hasn’t changed: most of the time in these sessions goes to design and reasoning about structure, not to debugging.
The second thing: diary grew from 108 entries to 251. The diary room isn’t per-project — it’s the stop hook’s checkpoint for any session — so that number is really a count of unattended saves: 251 checkpoints that happened without me doing anything.
The third thing: a room called disk, three drawers. That one came from a session where I’d asked Claude to hunt down files I could delete to free up disk space, and the extractor decided the topic deserved its own room.
What the extractor classified
The extractor works without an LLM — keyword and pattern matching on conversation content. It’s conservative. A session has to clearly match a pattern before a chunk gets classified.
Here’s a real example from the problems room — the SSH Git issue that came up during homelab setup:
ssh: connect to host localhost port 2222: Connection refused
The problem is that the SSH remote points tolocalhost:2222, but that port isn’t active.origin2points tolocalhost:2222, but Git SSH is exposed via NodePort30022on the server’s IP — not on localhost.
That chunk was classified correctly: it’s a problem, with a root cause, with two explicit solution options. The classifier caught it because “problem”, “Connection refused”, and the options structure match its patterns.
A real example from architecture, from the exploration of a private geospatial API project:
Key architectural docs:
/docs/architecture/decisions.md— ADRs justifying architectural choices. Schema layout:public,ref,raw,ingest,outbox. Container responsibilities, env vars, RabbitMQ exchanges.
That went into architecture because it describes system structure. It’s a chunk I’d want available when returning to that codebase weeks later — without having to re-read five files to reconstruct what I already know.
What doesn’t get classified: conversational back-and-forth, generic questions, incomplete exchanges. The 357 drawers in general are the residue — things that didn’t fit a specific room type but contained useful content.
What I asked the knowledge graph (KG)
The KG started empty. I seeded it manually with what I know about the current state of my projects. After a single session of adding triples, I could ask:
“What does User work on?”
User → works_on → personal-blog
User → works_on → geo-service
User → works_on → rural-registry
User → works_on → devops-toolkit
User → works_on → video-pipeline
User → works_on → content-studio
User → uses → Claude Code (since 2026-01-01)
User → uses → MemPalace (since 2026-01-01)The list above is trimmed for space — the graph tracks a dozen project wings by now, not four.
“What is the personal-blog stack?”
personal-blog → uses_framework → Hugo
personal-blog → uses_theme → theme-engine
personal-blog → deployed_on → home-cluster
personal-blog → serve_via → cloudflared“What does geo-service use?”
geo-service → uses_backend → FastAPI
geo-service → uses_db → PostgreSQL
geo-service → uses_extension → PostGIS
geo-service → deployed_on → home-clusterThat last query took one MCP call and returned structured results. Compare that to the alternative: searching the palace, parsing text, hoping the relevant session got mined before this one.
What I noticed looking at it from the outside
Everything deploys to home-cluster. Every active project — a dozen of them now, not the four I had the first time I ran this check — resolves to the same → deployed_on → home-cluster triple. I already knew that abstractly; seeing it spelled out as a dozen near-identical facts made the single point of failure concrete in a way the abstract version never did. If the home server has a bad day, none of it degrades gracefully — all of it goes down at once.
The sessions wing dwarfs everything else. More than it did the first time, in fact: 12,478 of 12,732 drawers are in the cross-project wing — 98%, up from 95%. That’s expected — the session hook runs on every conversation, and new projects mostly add conversations, not project-specific drawers — but it means the project wings are more underweight now than they were, not less. Right now they hold about 2% of the total knowledge, combined.
The extractor caught more this time. problems went from 4 drawers to 46 — a real jump, not noise. Some of that is just more sessions to mine; some of it is more actual debugging, since a couple of the newer projects are earlier-stage and messier. 46 out of 12,732 is still a small slice, but it no longer supports the idea that debugging is rare for me. Then again, a problem rate under half a percent is a margin I’d take any day.
The KG reveals what drawers can’t. A drawer knows the content of a session chunk. The KG knows the relationships between things. “What projects share the same infrastructure?” is a graph question, not a search question. Before building the KG, that answer required reading across wings. Now it’s a single query.
What the system is starting to enable
I can now ask things I couldn’t ask before — or couldn’t ask efficiently:
- “What projects use home-cluster?” → immediate structured answer
- “What was true about personal-blog on a given date?” → temporal query, as the graph grows
- “What tools do I consistently use?” → pattern across all projects, not just one session
None of this was possible when context lived only in my head, or only in text pasted at the start of each session. The system isn’t replacing judgment — it’s making history accessible in the same way that good documentation makes a codebase accessible: without having to rebuild understanding from scratch every time.
What’s still missing
The KG is empty of feedback. I’ve added project facts — what a project uses, where it deploys — but not the corrections and preferences that MemPalace already stores as drawers: “don’t do X because of Y”, “always Z before W”.
The gap isn’t vocabulary. A predicate for AI preferences already exists. The gap is shape: a triple is subject → predicate → object, three flat slots, and “because of Y” doesn’t fit into any of them without becoming a full sentence stuffed into the object. That gets me a fact I can look up, not one I can query structurally — which defeats the point of having a graph instead of just a drawer.
The extractor has a version of the same problem. It doesn’t know what’s important in a session, only what pattern-matches to “decision”, “problem”, or “milestone”. Signal and noise end up mixed together in the drawers. Semantic search papers over that reasonably well, but not perfectly.
Right now the KG holds 34 entities and 32 triples, all of them current — nothing has changed enough yet to force an invalidation. Every one of those triples, I added by hand.
That’s probably not a temporary state. The drawer extractor can skip the LLM because classifying a chunk as “looks like a problem” only needs to be right most of the time — a recall problem. Building a triple is a precision problem: the right subject, the right predicate from a fixed list, the right object, and a judgment call on whether it replaces something already in the graph. Pattern matching doesn’t do that kind of precision work. Automating this properly means putting an LLM in the loop at triple-creation time, not just adding another hook.
The thing worth keeping
The most interesting part of building this system wasn’t the setup. It was looking at what came out the other side.
Some of it was just numbers holding still under a new light: the architecture room still full, the problems room still thin, the sessions wing swallowing almost everything else. None of that needed a graph — a table of counts said it plainly enough.
What needed the graph was a different kind of question: not what a project is, but what it connects to. “Which projects deploy to home-cluster?” gets all twelve back in one query. Without the graph, getting the same answer means opening each of the twelve wings and checking by hand — slower, and easy to get wrong by missing one.
That’s the part worth keeping: not MemPalace specifically, but the framework it implements — separate layers for what a thing is, what happened to it, and how it connects to everything else. The tool could change. The stack of the solution, and the reason a graph is the piece that answers “how do things connect”, wouldn’t.