My Claude Code config costs 9,857 tokens before I type anything
I installed 107 skills, 38 agents and 15 commands into Claude Code over a few months. Standard stuff - you see a skill recommended somewhere, it looks useful, you drop it in. Nobody ever tells you to take one out. Last week I finally measured what that pile costs. The answer is 9,857 tokens, and I pay it on every single session before I type a character. Here is how to check yours. Skills have two costs, and everyone thinks about the wrong one A skill's body loads when the skill triggers. That cost is visible and roughly fair - you asked for the skill, you pay for the skill. A skill's description is different. Every description of every installed skill, agent and command sits in the context window for the whole session, whether or not the thing ever fires. It has to: that is how the model decides what is available. That is not a load cost. That is rent, and you pay it forever. The script Standard library only, one file, short enough to read before you run it against your home directory - which is the only sane way to run a stranger's script: #!/usr/bin/env python3 """cc-tax - what your Claude Code config costs before you type anything.""" import pathlib, re, sys CHARS_PER_TOKEN = 4 DESC_RE = re.compile(r"^description:[ \t](.?)(?=^[A-Za-z_][\w-]:|\Z)", re.S | re.M) FRONTMATTER_RE = re.compile(r"\A---\r?\n(.?)\r?\n---", re.S) BLOCK_MARKER_RE = re.compile(r"\A[>|][+-]?\d*\s*") def extract_description(text): fm = FRONTMATTER_RE.search(text) if not fm: return "" found = DESC_RE.search(fm.group(1)) if not found: return "" return BLOCK_MARKER_RE.sub("", found.group(1).strip()).strip().strip(""'").strip() def scan(root): sources = ( ("skill", sorted(root.glob("skills//SKILL.md")), lambda p: p.parent.name), ("agent", sorted(root.glob("agents/.md")), lambda p: p.stem), ("command", sorted(root.glob("commands/*.md")), lambda p: p.stem), ) return [(kind, name_of(p), len(extract_description(p.read_text(errors="ignore"))) / CHARS_PER_TOKEN) for kind, paths, name_of in sources for p in paths] root = pathlib.Path(sys.argv[1]).expanduser() if sys.argv[1:] else pathlib.Path.home() / ".claude" rows = scan(root) total = sum(r[2] for r in rows) for kind in ("skill", "agent", "command"): group = [r for r in rows if r[0] == kind] print(f"{kind + 's': 5}{sum(r[2] for r in group):>10,.0f}") print(f"{'TOTAL': 5}{total:>10,.0f}") for kind, name, cost in sorted(rows, key=lambda r: r[2], reverse=True)[:10]: print(f" {cost:>5,.0f} {name} ({kind})") Tokens are estimated as characters รท 4, the usual rule of thumb. A real tokenizer moves the absolute numbers a few percent and changes no ranking, which is why it is not worth a dependency. What mine said skills 107 7,470 agents 38 1,999 commands 15 388 TOTAL 160 9,857 About 5% of a 200k window, gone before anything happens. I want to be honest about that number rather than dress it up: 5% is not a catastrophe. The problem is not the size, it is the ratio. I pay it 100% of the time for components I trigger maybe 2% of the time. And it does not sit there alone - it stacks with the system prompt, tool definitions, every MCP server's tool schemas, your CLAUDE.md , and the actual files you need to read. The tax is not what breaks you. It is what leaves you with less room than you thought when something else does. The part that made me laugh The ten heaviest descriptions in my install: 244 loop-design-check (skill) 209 token-budget-advisor (skill) 184 prompt-optimizer (skill) 141 intent-driven-development (skill) 118 agent-architecture-audit (skill) Second place is token-budget-advisor - a skill whose entire purpose is helping me spend fewer tokens. It costs 209 tokens of permanent rent to offer to save me some. Body weight is even more lopsided. Total across 107 skills is ~322,990 tokens, median 1,932. The heaviest single skill is continuous-learning-v2 at 56,453 tokens per trigger - 29ร the median, more than a quarter of the context window in one shot. That one is also, as it turns out, half broken. The thing nobody puts in a README Once I started actually running the components instead of reading about them, a pattern showed up: - continuous-learning-v2 - the CLI works by hand. The automatic session observation, the entire reason to install it, needs hooks that are hard-wired to a full plugin install and silently absent in a selective one. - delivery-gate ,gateguard ,safety-guard - scripts present, but nothing registers them insettings.json . They advertise automatic enforcement. What you actually installed is documentation. - ck - itssession-start.mjs hook is not wired up, so the cross-session memory never loads itself. - deep-research - needs firecrawl or exa MCP. Without them it triggers, quietly degrades to ordinary web search, and keeps charging rent. The generalisable version: a skill that depends on an MCP server or a hook is not a skill you installed. It is a skill you started installing. The file lands, the description starts billing immediately, and the functionality shows up only after a second setup step nothing reminds you to do. There is no error. The skill just fires and underperforms, and you conclude the model is having an off day. One more number that reframes what a "skill" even is: of my 107 skills, 11 ship any file other than SKILL.md . The other 96 are pure prose. That is not automatically bad - a well-aimed paragraph steers a model better than most code. But it means the real question about the next skill someone recommends is not "is this good?" It is: is this paragraph worth permanent rent? For most skills in most social feeds, it is not. What I did about it Measured, then deleted anything I had not triggered in a month. Takes ten minutes and it is most of the value in this whole exercise, which is why the script above is the whole script and not a teaser. If it is useful to you, the file is on GitHub: Aliwers/cc-tax, MIT. I also wrote up the longer version - the full breakdown of which components are dead on arrival, how I cut a 284-skill pack down to 104 and the criteria I used, the rules-library trap that costs zero tokens and does nothing until deployed right, and the symlink setup for running one config across two machines without breaking anyone else's settings. That one is $5 here, and it exists because I am running a 48-hour challenge to build something small and make exactly one sale. This post is not a teaser for it - everything above is the actual finding. Go measure yours. I would genuinely like to know if anyone beats 9,857. Top comments (1) The distinction between context rent and execution cost is the exact right metric. Most tooling discussions treat token spend as purely transactional, but descriptive overhead behaves like an unindexed fixed tax on every turn. When a developer installs dozens of prose-only skills that silently degrade without external dependencies, they are paying perpetual token margin for inactive documentation. Pruning unused descriptions directly restores effective context headroom for actual codebase exploration.
Comments
No comments yet. Start the discussion.