Diff Token Counter
Parses a unified diff and estimates its tokens three ways: the whole patch, the changed lines only, and the changed lines without context.
Nothing is uploaded. Your patch is read with FileReader inside this tab and never leaves it — there is no server call on this page, and the text is kept out of the URL as well, so the link you share carries your settings and not your content.
2 files, 2 hunks, +13 −3. Sending it once costs $0.0014.
- Files touched
- 2
- Hunks
- 2
- Added lines
- 13
- Removed lines
- 3
- Context lines
- 7
- Header lines (diff --git, index, ---, +++)
- 8
- Whole diff
- 452 tokens
- Added lines only
- 144 tokens (31.9%)
- Added and removed, no context
- 168 tokens (37.2%)
- Context lines alone
- 76 tokens (16.8%)
- At 500 diffs a month
- $0.68
Estimated, not tokenized. Token figures here come from an approximation running in your browser: no tokenizer vocabulary is downloaded, because a real one is megabytes and nothing on this page fetches anything. It imitates how a byte-level BPE splits text — words, digit groups, punctuation runs, whitespace runs — but it has no merge table, so treat it as a planning number. The authoritative count is the usage object on a real API response.
Per file
| File | + | − | Context | Est. tokens | |
|---|---|---|---|---|---|
| lib/billing/ledger.ts | 7 | 3 | 4 | 255 | |
| tests/concurrency.mjs | 6 | 0 | 3 | 169 |
diff --git starts a file, @@ starts a hunk, and the first character of a body line is +, − or a space. A line inside the patch that happens to start with + because the code does is counted as an addition, which is what git itself would show. The "added lines only" and "no context" figures strip the leading marker character, so they measure the content rather than the notation. Nothing here counts the tokens of the instruction you wrap the diff in, which is usually a few hundred more.A diff is the cheapest complete description of a change, and it is still bigger than people expect. Three separate things are being paid for: the changed lines, the context lines git includes around them (three above and three below by default, so a one-line fix ships seven lines), and the header noise — diff --git, index 8f2a1c4..b7d90e2, two file paths — repeated for every file touched. On a patch that renames forty files and edits one line in each, the headers are most of the bill.
The three figures above exist so you can choose. Sending the whole diff is right when the model needs to know what the code looked like before, which is most of the time for review. Sending added lines only is enough for "write a changelog entry" or "does this need a test", and it is often less than half the tokens. Dropping context but keeping both sides of the change is the middle option, and it is the one that goes wrong quietly — a model that cannot see the surrounding function will happily comment on a hunk it has misunderstood.
Two knobs on the git side move this more than any prompt engineering. --unified=0 removes context entirely and --stat gives you a file-level summary for a tiny fraction of the tokens, which is a good first pass when you want the model to pick which files to look at properly. And if you run this on a diff that includes a lock file or generated output, the per-file table will show you immediately — one path holding ninety percent of the tokens is the most common reason an automated review costs ten times what it should.