Billing is per token, not per byte or character. The byte to token ratio is content-dependent and model-specific; only the model's tokenizer tells you the exact count.
Imagine a courier that charges by parcels, not by weight. You arrive with a bag of stuff and the courier breaks it into parcels according to their own rules. English text packs neatly: about 3 to 4 characters per parcel. Minified JSON or Python code does not pack neatly, because the courier's rules were built for prose and weird punctuation breaks at the seams. Hindi or Japanese characters use up parcels at a different rate again, because the rules learned during training were trained on mostly-English text and never saw enough non-Latin characters to compress them well. So 1 KB of English costs about 250 parcels; the same 1 KB of code or non-English text can cost twice as much. The only way to know your real bill is to run the courier's own ruler over your specific bag.
Concept explanation~2 min read
Everything you need to truly understand this topic: intuition, mechanics, step by step explanation, code, formulas, and worked example. Click to expand.
Concept explanation~2 min read
Everything you need to truly understand this topic: intuition, mechanics, step by step explanation, code, formulas, and worked example. Click to expand.
Tokens are the unit every LLM API bills on, every context window is measured in, and every rate limit applies to. Despite this, most engineering teams reason about tokens using rules of thumb borrowed from character counts. That heuristic breaks down on real workloads, sometimes by 4x or more, and the resulting cost estimates miss reality by a meaningful margin.
This deep dive defines bytes, characters, and tokens precisely; explains why the byte to token ratio is content-dependent; surveys the major production tokenizers in 2026 and how they differ; and ends with the operational practices that production teams use to count tokens correctly.
Three different units of measurement
Bytes are the storage representation. UTF-8 encodes Unicode codepoints into 1 to 4 bytes per character. ASCII characters take 1 byte; most accented Latin characters take 2 bytes; many CJK characters take 3 bytes; emoji and some scripts can take 4. The byte count of a string is fixed by its UTF-8 encoding and easy to measure.
Characters are the logical units of text. In code and most APIs, a character is a Unicode codepoint. The distinction from bytes matters: 'café' is 4 characters but 5 bytes in UTF-8 (the é is a 2-byte codepoint). For visual character counts, you sometimes need grapheme clusters (multi-codepoint emoji, combining diacritics), but for token-count discussion the codepoint definition is what matters.
Tokens are the units the model actually processes. The tokenizer is a learned function that maps byte sequences to integer IDs from a fixed vocabulary. Different tokenizers produce different token sequences for the same input. Tokens are the level at which the model attends, the level at which the context window is measured, and the level at which providers bill.
The relationship between these three levels is direct from bytes to characters (deterministic UTF-8 decoding) and content-dependent from characters to tokens (the tokenizer compresses some patterns better than others).
Situations where this technique stops working.
2–4 min · Everything important, quickly.
Real products, models, and research that use this idea.
- OpenAI's `tiktoken` library counts tokens locally; `tiktoken.encoding_for_model('gpt-4o')` returns the o200k_base encoder used for billing.
- Anthropic's `messages.count_tokens` endpoint returns the exact billable token count for a Claude prompt before submitting it.
What an interviewer would ask next. Try answering before peeking at the approach.
QWhy does the same text cost more tokens in cl100k_base than in o200k_base?
o200k_base has roughly twice as many vocabulary entries and was trained on a more recent and multilingual corpus. More entries means more multi-character patterns get a single token, especially for code and non-English text. The compression gain is ~5% for English and 1.5x to 4x for non-Latin scripts.
Red flags & common mistakes
The phrases that signal junior thinking. Click to expand.
Red flags & common mistakes
The phrases that signal junior thinking. Click to expand.
Estimating cost by character count. Tokenizers compress differently across content types, so character-based estimates can be off by 2x or more for code and non-Latin text.
60 second bullets to scan on the way to the call.
Primary sources. Browse if you want the original framing.
Same topic, related formats. Practice these next.