· via dev.to (home feed)
Experiment maps which CLAUDE.md files reach Claude Code, and what each costs in tokens
A dev.to experiment tags six CLAUDE.md files with codewords and measures the result: three load at launch at roughly 1,600 tokens each, subdirectory files arrive only after a Read, and a --add-dir file needs an env var.

What the experiment did
An experiment published on dev.to set out to answer a question most Claude Code users have probably wondered about: of the various CLAUDE.md files a machine tends to accumulate, which ones actually reach the model, when do they arrive, and what does each one cost?
The author built a test lab with six memory files in six locations: a parent directory above the working directory, the working directory itself (holding both CLAUDE.md and CLAUDE.local.md), two nested subdirectories, and a sibling directory reachable only through --add-dir. Each file carried a unique codeword such as CW-PARENT-4417 or CW-SUBDIR-6621, padded with filler so every file landed between 4,543 and 4,669 bytes. Equal sizes meant any difference in token counts reflected loading behaviour, not file size.
All runs used Claude Code v2.1.273 on 2026-09-16 with the same model, inside a throwaway directory created with mktemp -d. The probe prompt asked the model to list every CW- string visible in its context without calling tools. The author did not rely on the model's answers alone, also reading per-request token usage and attachment records from the transcripts Claude Code writes under ~/.claude/projects/.
Three files in, two free
At launch, three of the six files were delivered to the model, in this order: the parent-directory CLAUDE.md, the project CLAUDE.md, then CLAUDE.local.md. That ordering runs from the filesystem root down to the working directory, with the local variant appended after the regular file in the same directory.
The numbers, per the dev.to writeup: a baseline session with no CLAUDE.md anywhere consumed 18,442 input tokens in the first request. Adding the project CLAUDE.md raised that by 1,638 tokens; CLAUDE.local.md added another 1,559; the parent file added 1,594. Adding the two subdirectory files changed the total by exactly zero.
One notable detail: the parent file sat above the repository's git root, yet the transcript typed it as Project, identical to the repository's own file. The directory walk does not stop at the repository boundary, and nothing in the attachment marks that file as coming from outside the repo.
CLAUDE.local.md also proved switchable. Running with --setting-sources set to user,project dropped the first request to 21,674 tokens — exactly the 1,559 tokens the local file had been costing.
Subdirectory files load only on demand
To trigger the subdirectory files, the author changed the prompt so the model would make a single Read call. Reading a control file in the working directory grew the second request by just 154 tokens, the cost of the tool call and its one-line result. Reading sub/data.txt grew it by 1,787 tokens, with the transcript showing sub/CLAUDE.md arriving as a nested_memory attachment — roughly 1,630 tokens net for the file itself, about 40 tokens more than the same-sized parent file cost at launch, a gap the author did not explain.
Reading a file in sub/deep/ loaded two records in order — sub/CLAUDE.md, then sub/deep/CLAUDE.md — for a total growth of 3,380 tokens. In other words, one read several levels down pulls in every CLAUDE.md between the working directory and the target file, not merely the nearest one.
The file that never arrived
The memory file in the extra directory, reachable only via --add-dir, never reached the model at all — not even after the model read a file inside that directory — until the author set an environment variable to allow it. This is consistent with the Claude Code documentation, which states that CLAUDE.md files from --add-dir directories are not loaded by default.
Measurement noise, and how it was removed
The first ten runs exposed a measurement hazard: two identical configurations returned 23,624 and 24,410 input tokens. The only transcript difference was a remote connector's tool list, apparently a startup race the author did not fully confirm. Adding --strict-mcp-config and disabling hooks per run through a settings override made every subsequent pair of runs match exactly. The early runs were discarded, leaving 28 clean ones.
Why it matters
Every launch-time CLAUDE.md file costs around 1,600 tokens on every request a session makes, so projects stacked with parent, project and local memory files pay that overhead continuously — and a stray CLAUDE.md in a directory above your repository silently joins the context, typed as project memory. The flip side is good news for monorepo users: subdirectory memory is free until a file below it is actually read, though deep reads cascade in every intervening file at once. And anyone relying on --add-dir directories to contribute memory files is, by default, not getting them at all.
- #claude-code
- #anthropic
- #llm
- #developer-tools
- #context-management