Build1 publisher3 min readPublished
Scoping a Claude rules file to src/api/** kept 3,330 tokens out of the first request
A dev.to test put the same 2,004-word rule set in four locations on Claude Code v2.1.263 and measured the first request of a fresh session. Only the path-scoped file kept its words out of the launch prompt.
The Engineer · Build desk

What happened
- The same 2,004-word rule set placed inline in CLAUDE.md added 3,330 tokens to the first request of a fresh Claude Code session, measured on one machine with one body of text.
- Adding paths: ["src/api/**"] to the rules file made the first request cost nothing extra, and it stayed at zero until Claude read a file under src/api/, when the rule arrived for 2,987 tokens.
- The session transcript shows an attachment record of type nested_memory carrying the full rule text right after the matching Read, and no such record in the non-matching run.
Compiled by The EngineerSomething wrong?How this is made
Why it matters
- constraint Splitting a long instruction file into @import files buys tidier files and no context relief, so the docs' warning about 200-line files cannot be answered by moving text between files.
- decision The paths frontmatter is the only lever measured here that changes the launch bill, so teams have to decide which rules can be attached to a file pattern at all; anything that applies everywhere stays in the launch prefix unconditionally.
- cost An agent that works inside the matching glob saves 343 tokens against inline placement, not 3,330; the full saving only lands on sessions that never touch src/api/.
- exposure A rule behind a glob is out of reach whenever the agent is working elsewhere, so any rule you cannot afford to have missing does not belong in a scoped file.
The measurement is cheap to repeat. The prompt was `claude -p "Reply with just OK." --output-format json --max-turns 1`, and the total for each run is input_tokens plus cache_read_input_tokens plus cache_creation_input_tokens from the usage block of the JSON output [10][11]. Every configuration ran twice, and the second run read the whole prefix from cache and came back within two tokens of the first [12]. So the figure being compared is everything the model was handed before it did any work.
At launch, `@import` moves text from one file into another. Claude Code's memory docs say imports "helps organization but doesn't reduce context, since imported files load at launch" [6]. The measured import lands 112 tokens above the inline version, at 3,442 against 3,330 [22]. An unscoped file under `.claude/rules/` costs 108 tokens more than inline, and the writer attributes that gap to the file path and the wrapper Claude Code puts around a nested memory file [14].
The `paths` frontmatter behaves differently, and the transcript shows how. Claude Code reads the frontmatter to know when the file applies, and the first request comes back byte-for-byte identical to the baseline [15]. Immediately after the Read result for `src/api/handler.ts`, the transcript that `claude -p` writes under `~/.claude/projects/` carries an attachment record of type `nested_memory` whose path is `.claude/rules/api.md` and whose content is the full rule text; the non-matching run has no such record [19]. Nested CLAUDE.md files in subdirectories arrive on the same channel [20].
Delivery is not free. The matching run created 11,597 cache tokens across its two requests against 8,610 for the non-matching run, so the rule set cost 2,987 tokens when it landed [21]. Inline, the same text cost 3,330, which makes the scoped delivery 343 tokens cheaper, about ten percent [23]. For an agent whose session lives in `src/api/`, that 343 is the whole saving. The zero holds only while nothing matches the glob.
Scoping also decides what the model can answer. Told to read `src/ui/button.ts` and then say whose job retries are, Claude replied "UNKNOWN" and noted that the rules it had say nothing about retries; the same question after reading `src/api/handler.ts` got "the caller", which is what rule 40 says [17][18].
For the numbers to transfer, your rules text has to be about the size of this one: forty numbered bullets, 12,135 characters, 2,004 words, which came to roughly 1.66 tokens per word inline [13][24]. One build was tested, v2.1.263, on 2026-09-10, with one rules file and one pattern [9]. Several rules files with overlapping globs were not measured. Neither was the docs' other claim, that files over 200 lines "consume more context and may reduce adherence" [8]; this run counted tokens, and adherence is a separate test.
The experiment does not survey how teams have actually organised their instruction files, so it cannot say how much of this bill is being paid in the wild. Both runs in the second experiment took two turns [18], too short to show how often the attachment reloads in a long session. The docs say nested memory files "reload as Claude reads files they apply to" after compaction [20].
What to watch
- Whether the 2,987-token attachment reloads once per compaction or on every matching read in a long session; two-turn runs cannot separate the two.
- Whether the four numbers hold on a Claude Code build after v2.1.263, since the launch prefix is a build detail.
- Whether the zero survives several rules files with overlapping globs rather than one file with one pattern.