CLAUDE LABJP
QUOTA — The 50 percent weekly usage boost for Claude Code subscribers ended on August 19. Allowances are back to standard today, so long agent runs need rethinking across the weekCONTEXT — v2.1.234 cut the built-in claude-api skill from over 200k tokens to roughly 25k by loading its reference docs on demand rather than all at oncePERMISSIONS — In v2.1.235, permission dialog text and what a grant actually covers now always match, and the don't ask again option is withheld when contents cannot be fully shownCACHE — Fixed whole-prompt-cache invalidation when a language server disconnected or reconnected mid-session, which had been quietly hurting hit rates on long sessionsSESSION — Claude Code now continues your session automatically when a claude.ai usage limit resets. Turn it off under Continue automatically at usage limit in /configPRICING — Claude Sonnet 5's introductory $2 per million input and $10 output ends August 31; standard $3 and $15 pricing starts September 1, eleven days outQUOTA — The 50 percent weekly usage boost for Claude Code subscribers ended on August 19. Allowances are back to standard today, so long agent runs need rethinking across the weekCONTEXT — v2.1.234 cut the built-in claude-api skill from over 200k tokens to roughly 25k by loading its reference docs on demand rather than all at oncePERMISSIONS — In v2.1.235, permission dialog text and what a grant actually covers now always match, and the don't ask again option is withheld when contents cannot be fully shownCACHE — Fixed whole-prompt-cache invalidation when a language server disconnected or reconnected mid-session, which had been quietly hurting hit rates on long sessionsSESSION — Claude Code now continues your session automatically when a claude.ai usage limit resets. Turn it off under Continue automatically at usage limit in /configPRICING — Claude Sonnet 5's introductory $2 per million input and $10 output ends August 31; standard $3 and $15 pricing starts September 1, eleven days out
Articles/Claude Code
Claude Code/2026-08-20Advanced

The Biggest Section in Your SKILL.md Is Usually the One to Keep

A skill I run every week cost about 10K tokens just to load. Measuring it section by section showed why the largest block was the one I had to leave in place, and what splitting by reach actually saved.

Claude Code226SKILL.md7progressive disclosure2context design3indie development18

Premium Article

I invoked the skill I use to sort wallpaper source images, and the first response took noticeably longer than it used to. The sorting procedure itself had not changed. All I had added were stricter rules for the categories that keep getting mixed up, plus the steps for pushing merged categories to the API.

When I measured the file, that single SKILL.md came to roughly 10,000 tokens. All of it was in context before we had discussed a single image.

In Claude Code v2.1.234, released on August 17, the context cost of loading the built-in claude-api skill dropped from over 200K tokens to about 25K, because reference documentation is now read at the point where it is actually needed. Deciding to do the same thing to my own skills was the easy part.

The hard part was choosing which sections to move out. My first instinct was to start with the largest one, and that turned out to be wrong.

Nothing has happened yet, and the context is already spent

In Claude Code, only a skill's description stays resident. The body of SKILL.md loads when the skill is invoked. So the size of the body is not a standing cost — it is a startup cost. Getting this backwards leads you toward pruning skills you rarely use, when the thing that actually matters is how much lands the moment you invoke the one you use daily.

As an indie developer running several apps and sites in parallel, I find my skills grow on their own. The wallpaper categorization skill carries decision rules for 30 categories, and over time I bolted on stricter rules for the categories that attract misclassification. Every line got there because something went wrong once. That is exactly why I could not trim it by feel.

So I started by measuring.

A small audit script that measures section by section

The idea is simple: split SKILL.md on H2 and H3 headings, count tokens per section, and sort descending. That alone tells you where your context went.

Claude's tokenizer is not public, so this uses tiktoken with cl100k_base. The absolute numbers are not exact. Treat them as a ruler for comparing sections against each other. There is a character-class fallback so the script still runs where tiktoken isn't installed.

#!/usr/bin/env python3
"""Measure the context cost of a SKILL.md section by section.
 
Usage:
    python3 skill_context_audit.py path/to/SKILL.md
    python3 skill_context_audit.py path/to/SKILL.md --split out_dir
 
Add a reach annotation (an HTML comment) right after a heading to group
sections by how likely a given run is to reach them. Untagged sections
are treated as always.
"""
import argparse, os, re, sys
 
try:
    import tiktoken
    _ENC = tiktoken.get_encoding("cl100k_base")
    def count_tokens(text: str) -> int:
        return len(_ENC.encode(text))
    TOKENIZER = "cl100k_base"
except ImportError:
    # Fallback: CJK chars run about 0.7 tokens each, ASCII about 4 chars per token
    def count_tokens(text: str) -> int:
        cjk = sum(1 for c in text if ord(c) > 0x2E80)
        return int(cjk * 0.7 + (len(text) - cjk) / 4)
    TOKENIZER = "approx"
 
REACH_RE = re.compile(r"<!--\s*reach:\s*([a-z0-9_]+)\s*-->")
HEADING_RE = re.compile(r"(?m)^(#{2,3} .*)$")
 
 
def split_sections(md: str):
    """Return [(heading, block-including-heading)]; the first entry is __head__."""
    parts = HEADING_RE.split(md)
    sections = [("__head__", parts[0])]
    for i in range(1, len(parts), 2):
        body = parts[i + 1] if i + 1 < len(parts) else ""
        sections.append((parts[i].strip(), parts[i] + "\n" + body))
    return sections
 
 
def reach_of(block: str) -> str:
    m = REACH_RE.search(block)
    return m.group(1) if m else "always"
 
 
def audit(path: str):
    md = open(path, encoding="utf-8").read()
    sections = split_sections(md)
    rows = [(h, reach_of(b), count_tokens(b)) for h, b in sections]
    total = sum(r[2] for r in rows)
 
    print(f"file      : {path}")
    print(f"tokenizer : {TOKENIZER}")
    print(f"total     : {total} tok / {len(md)} chars\n")
    print(f"{'tok':>7} {'share':>6}  reach     heading")
    for h, reach, t in sorted(rows, key=lambda r: -r[2]):
        print(f"{t:7d} {t * 100 / total:5.1f}%  {reach:<9} {h[:56]}")
 
    by_reach = {}
    for _, reach, t in rows:
        by_reach[reach] = by_reach.get(reach, 0) + t
    print("\n-- by reach --")
    for reach, t in sorted(by_reach.items(), key=lambda kv: -kv[1]):
        print(f"  {reach:<10} {t:6d} tok ({t * 100 / total:4.1f}%)")
 
    resident = by_reach.get("always", 0)
    print(f"\nstartup cost with only always sections in the body: {resident} tok"
          f"({(1 - resident / total) * 100:.1f}% lower)")
    return rows, total

Here is the output for the wallpaper categorization skill I actually run.

file      : .claude/skills/wallpaper-category/SKILL.md
tokenizer : cl100k_base
total     : 10048 tok / 14372 chars
 
    tok  share  reach     heading
    980   9.8%  always    ### 1. Batch processing (with rate-limit handling)
    849   8.4%  always    ### Automatic merge (every 100 images)
    755   7.5%  always    __head__
    596   5.9%  always    ## Mutual exclusion rules between categories
    586   5.8%  always    ### 3. Applying merged categories to the API
    481   4.8%  always    ### 3D — strict rules (frequent misclassification)
    458   4.6%  always    ### Typography — strict rules (frequent overlap)

14,372 characters, about 10,048 tokens. The file is mostly Japanese, so it weighs more than the character count suggests — roughly 0.7 tokens per character. If you write skills in a non-Latin script, that ratio is worth internalizing. A line-count budget will never show it to you.

I wrote about line-count budgets earlier in The Second Half of My SKILL.md Wasn't Being Read. This piece picks up where that one stops: once you have a ceiling, which sections actually leave?

Thank you for reading this far.

Continue Reading

What follows includes implementation code, benchmarks, and practical content we hope you'll find useful. This site runs without ads — server and development costs are supported entirely by members like you. If it's been helpful, we'd be truly grateful for your support.

WHAT YOU'LL LEARN
You'll be able to see, section by section, which parts of your own SKILL.md are consuming context at load time
You'll be able to avoid the common mistake of extracting your largest section and paying for it in repeated lookups
You'll be able to decide when a multi-session workflow should become two skills instead of one skill with reference files
Secure payment via Stripe · Cancel anytime

Unlock This Article

Get full access to the rest of this article. Buy once, read anytime. This site is ad-free — your support goes directly toward keeping it running.

or
Unlock all articles with Membership →
Share

Thank You for Reading

Claude Lab is ad-free, supported entirely by members like you. We publish practical guides daily with implementation code, benchmarks, and production-ready patterns. If you've found it useful, we'd love to have you on board.

  • Copy-paste ready implementation code
  • New advanced guides published daily
  • $5/mo or $10 for lifetime access
View Membership →

Related Articles

Claude Code2026-08-17
Now that forking is the default, review agents are the ones I still call by name
Subagent forking became the default, so delegated work now inherits the parent conversation. Work can inherit context. Judgment cannot. Here is how I declare that boundary in the repository and catch it drifting.
Claude Code2026-05-30
The Second Half of My SKILL.md Wasn't Being Read: Keeping It Under 200 Lines
Sparked by an observation that Codex CLI stops reading SKILL.md at around 220 lines, a look at how long an agent actually reads, and how to keep SKILL.md under 200 lines by offloading detail into references.
Claude Code2026-08-10
The Same rm -rf Was Recoverable in Ten Places and Unrecoverable in Five — Measuring Reversibility Before Auto Mode Becomes the Default
Auto mode becomes the default on Pro, Max and Team from August 14. It stops on operations judged irreversible, destructive, or outward-facing — but reversibility turned out to be a property of state, not of commands. Here is the probe and the measurements.
📚RECOMMENDED BOOKS
Build a Large Language Model (From Scratch)
Sebastian Raschka
LLM Dev
Prompt Engineering for LLMs
Berryman & Ziegler
Prompting
AI Engineering
Chip Huyen
AI Eng
* Contains affiliate links
See all →