← Writing

Omar Bohsali

Counting What the Model Pays For: tc and tokdump

A single lockfile or inline SVG can quietly burn 40% of a context window on every turn. Two small Unix tools make o200k_base token weight visible in local shells and CI.

brew install omarish/tap/tc omarish/tap/tokdump
tctc counting tokens in three files, then in a pipeline.tc$tc README.md main.go encoding.go2288 README.md1304 main.go389 encoding.go3981 total$printf 'Explain this diff.' | tc4$Counts tokens, not characters or words.Always o200k_base -- the encoding GPT-4oreads.One count per file, then a total. The sameshape wc has printed since 1971.With no files it reads stdin, so it dropsinto a pipeline without ceremony.
tc counts o200k_base tokens across files and standard input with the same flags and output columns as wc(1).

Unix tools were built around bytes and newline characters because bytes and lines were what disks and terminals paid for. Language models do not pay by the line; they pay by the o200k_base token11. A 400-line minified SVG or JSON fixture can easily outweigh 2,000 lines of clean Python because punctuation and high-entropy hex strings shatter into single-byte tokens..

When an agent reads a directory, a single committed snapshot or generated asset can silently consume forty percent of its context window on every turn. Nothing in ls -lh or wc -l warns you that a file is three times heavier to a tokenizer than its byte count suggests.

tc: wc(1) for tokens

We wrote tc to drop directly into existing shell pipelines. Give it a list of files or pipe standard input to it, and it prints exact o200k_base token counts in milliseconds:

# Find the heaviest files in a package before handing it to an agent
tc src/**/*.py | sort -n | tail -n 10

tokdump: hexdump(1) for byte-level BPE

When a file has a surprisingly high token-to-byte ratio, tokdump shows you why. It formats standard input into three columns—hex byte offset, integer token IDs, and visible token boundaries—so you can see exactly where the BPE state machine splits UTF-8 sequences, identifiers, and punctuation:

tokdumptokdump showing where a string splits into tokens.tokdump$printf 'Hello, world!' | tokdump0000000 13225 11 2375 0 Hello|,|·world|!0000004$printf '💯🔥' | tokdump -n0000000 31446 107 \xf0\x9f\x92|\xaf0000002 96606 🔥0000003$Three columns: offset, token IDs, and thetext they cover. The layout hexdump has usedsince 1978.Two emoji. The first costs two tokens andsplits mid-character; the second is a singletoken.Narrow: two token IDs per row instead offour.
tokdump showing byte offsets, token IDs, and sub-word splits on UTF-8 input.

Both tools are small, dependency-light, and open source. Run them locally in your shell or add a five-line check in CI so no pull request accidentally doubles the token weight of your core modules.