/token-audit — Context Token Audit logo

/token-audit — Context Token Audit

FlorianBruniaux/claude-code-ultimate-guide

Summary

Audit Claude Code configuration to measure fixed-context token overhead and produce a prioritized action plan

SKILL.md

/token-audit — Context Token Audit

**Purpose**: Measure how many tokens your Claude Code configuration consumes before any user task begins. Identify the biggest sources of overhead. Produce a concrete action plan with savings estimates.

**When to use**:

  • You're hitting rate limits before end of day
  • Sessions feel slow or context compresses early
  • You've added a lot of rules files and want to know the real cost
  • After a major config change

---

What You Will Measure

| Component | Loaded when | Typical range | |-----------|-------------|---------------| | `~/.claude/CLAUDE.md` + @imports | Always | 5-15K tokens | | Project `CLAUDE.md` | Always | 2-8K tokens | | `.claude/rules/*.md` | Always (all files) | 5-40K tokens | | `MEMORY.md` | Always | 1-3K tokens | | Claude Code system prompt | Always | ~7,500 tokens | | Hook stdout | Per tool call | variable | | Commands, agents, skills | On invocation only | 0 by default |

Key insight: `.claude/rules/` loads every `.md` file at session start, regardless of relevance. Commands and agents are lazy-loaded — they cost zero until invoked. Rules files are the most common source of unexpected overhead.

---

Step 1 — Run the Measurement

Execute these commands from the project root:

# Component sizes
echo "=== PROJECT CLAUDE.md ===" && wc -c CLAUDE.md 2>/dev/null || echo "none"

echo ""
echo "=== RULES FILES (sorted by size) ===" && find .claude/rules -name "*.md" 2>/dev/null \
  | xargs wc -c 2>/dev/null | sort -rn | head -20

echo ""
echo "=== GLOBAL ~/.claude ===" && ls -la ~/.claude/*.md 2>/dev/null \
  | awk '{print $5, $9}' | sort -rn

Then calculate the full budget:

GLOBAL=$(cat ~/.claude/CLAUDE.md ~/.claude/*.md 2>/dev/null | wc -c)
PROJECT=$(wc -c < CLAUDE.md 2>/dev/null || echo 0)
RULES=$(find .claude/rules -name "*.md" 2>/dev/null | xargs cat 2>/dev/null | wc -c || echo 0)
MEMORY=$(find ~/.claude/projects -name "MEMORY.md" 2>/dev/null \
  | xargs grep -l "$(basename $(pwd))" 2>/dev/null | head -1 \
  | xargs wc -c 2>/dev/null | awk '{print $1}' || echo 0)
TOTAL=$(( GLOBAL + PROJECT + RULES + MEMORY + 30000 ))

echo "Global ~/.claude   : ~$(( GLOBAL / 4 )) tokens ($(( GLOBAL / 1000 ))K chars)"
echo "Project CLAUDE.md  : ~$(( PROJECT / 4 )) tokens"
echo "Rules (auto-loaded): ~$(( RULES / 4 )) tokens"
echo "MEMORY.md          : ~$(( MEMORY / 4 )) tokens"
echo "System prompt      : ~7,500 tokens"
echo "---"
echo "TOTAL fixed context: ~$(( TOTAL / 4 )) tokens"
echo "% of 200K window   : $(( TOTAL / 4 * 100 / 200000 ))%"

---

Step 2 — Classify Rules Files

For each file in `.claude/rules/`, classify it:

| Class | Definition | Action | |-------|------------|--------| | **ALWAYS** | Applies to most tasks (conventions, output format, safety) | Keep auto-loaded | | **SOMETIMES** | Relevant in 20-40% of sessions | Keep if small (<3K chars); lazy-load if large | | **RARELY** | Relevant in <10% of sessions (Figma, Windows, design system) | Remove from auto-load | | **NEVER** | Outdated or covered elsewhere | Delete or archive |

Run this classification prompt:

Read every file in .claude/rules/. For each file, output a table row:

| File | Size (chars) | Class (ALWAYS/SOMETIMES/RARELY/NEVER) | Reasoning (one sentence) |

Sort by size descending within each class.
At the end, calculate: total chars that would leave the fixed context if all
RARELY and NEVER files were excluded. Convert to tokens (÷ 4).

---

Step 3 — Audit Hook Overhead

Hooks on `PreToolUse` and `PostToolUse` fire on every tool call. Each invocation injects its stdout into context. A hook outputting 500 chars on 150 tool calls per session = 75K chars ≈ 19K extra tokens.

Check what you have:

# List hoo

<!-- truncated -->

View raw file