[BUG] Startup blocks for seconds parsing path-scoped .claude/rules/*.md prose that is never injected into context (cost ∝ prose size)

Status Open
Reported on v2.1.220
Maintainer reply None cached
Activity 0 comments · opened Aug 2, 2026

Preflight Checklist

  • [x] I have searched existing issues and this hasn't been reported yet (closest are #76118 — runtime re-injection on Read, #47897 — double-load under worktrees, #71686 — size-budget drop; none cover startup CPU cost)
  • [x] This is a single bug report
  • [x] I am using the latest version of Claude Code

What's Wrong?

In a project carrying a large .claude/rules/ directory (15 path-scoped files, 596KB total), claude takes ~8.3s to complete a trivial -p one-shot vs ~3.2s in an empty directory. Interactively the same delay shows up as several seconds of unresponsive UI at launch: no statusline, keystrokes not echoed.

The entire delta is local CPU spent processing the rules files at startup — the rules are path-scoped and are not injected into context (API token usage is identical with and without them; see logs below). The cost scales with the prose content of the files, not file count and not raw bytes:

| .claude/rules/ content | Startup (avg of 3, -p 'reply with only: ok' --model haiku) |
|---|---|
| none (baseline, empty git repo) | ~3.2s |
| 15 real rules files, 596KB | ~8.0s |
| same 596KB, paths: frontmatter stripped | ~10.7s |
| 840KB base64 filler, 15 files | ~2.9s (≈ free) |
| 780KB plain-English filler, 15 files | ~5.7s |
| same English filler, every 3rd word backticked | ~2.3s |
| 1 × 340KB file vs 2 × 170KB files | same (~9–10s) |

So the hot path scans natural-language prose per-word/per-token (dense English costs ~3–8ms/KB; base64 and code-span-heavy text is nearly free). With a rules corpus in the hundreds of KB this adds seconds of startup latency. The interleaved A/B runs (plain vs backticked filler, 4 rounds) reproduce the 2.5× gap consistently, so it is not machine noise.

What Should Happen?

Path-scoped rules that match nothing should cost ~0 at startup. Whatever indexing/parsing is needed should be deferred, incremental, or cached across sessions (the files rarely change between launches), and should not block the input loop / statusline.

Error Messages/Logs

# No errors — pure latency. Evidence the rules are NOT sent to the API:
# --output-format json usage for the same prompt:
#   empty dir baseline:        cache_creation_input_tokens: 4643
#   dir with 596KB rules:      cache_creation_input_tokens: 4522   (identical modulo noise)
# time(1) confirms the cost is local CPU:
#   baseline:      real 3.9s  user 1.0s  sys 0.2s
#   596KB rules:   real 7.3s  user 3.0s  sys 2.6s

Steps to Reproduce

  1. Create a fresh repo with prose-heavy rules files:

``bash
mkdir -p /tmp/rules-repro/.claude/rules && cd /tmp/rules-repro && git init -q
python3 - <<'EOF'
import random
words=['the','sidebar','session','workspace','window','control','command','focus',
'render','surface','terminal','keymap','toggle','overlay','split','pane',
'status','flag','notify','restore']
random.seed(1)
for i in range(15):
with open(f'.claude/rules/f{i}.md','w') as f:
f.write(f'# rule {i}\n\n')
for _ in range(500):
f.write('- ' + ' '.join(random.choices(words,k=14)) + '.\n')
EOF
``

  1. time claude -p 'reply with only: ok' --model haiku → ~2.5s slower than the same command in an empty directory.
  2. Control — same bytes as base64, cost disappears:

``bash
rm .claude/rules/*.md
for i in $(seq 1 15); do head -c 40000 /dev/urandom | base64 > .claude/rules/f$i.md; done
time claude -p 'reply with only: ok' --model haiku # ≈ baseline
``

  1. Real-world rules files (dense prose with inline code spans) cost roughly 2× the filler prose per KB — ~5s total at 596KB in the project this was found in.

Claude Model

Not sure / Multiple models (measured with --model haiku to keep API time constant; session default is Opus — delay is model-independent)

Is this a regression?

I don't know

Last Working Version

_No response_

Claude Code Version

2.1.220 (Claude Code)

Platform

Anthropic API

Operating System

Other Linux (Manjaro, kernel 6.12)

Terminal/Shell

Other (agterm/ghostty; also reproduces with -p non-interactive, so terminal-independent)

Additional Information

  • Cost is per-bytes-of-prose, not per-file: one 340KB file ≈ two 170KB files.
  • Stripping the paths: frontmatter makes it slower (~10.7s) — presumably the rules then load unconditionally — but with frontmatter intact the parse cost is paid anyway even though nothing is injected.
  • The 15 real rules files that surfaced this are a working project's path-scoped engineering notes (biggest: 170KB, 88KB); the corpus is deliberate, not pathological.

View original on GitHub ↗