Blog

Token counting explained: why your bill surprised you

4 min read

Every LLM API bills by the token, not the character or the word, and a token is a model-specific unit — a tokenizer's output, not a fixed linguistic thing. That's the root of almost every "why is my bill higher than I expected" moment: teams estimate cost using word count or character count, and the actual token count for their specific content and specific model comes in meaningfully different.

Why the ratio isn't fixed

A rough rule of thumb — about four characters per token, or roughly 0.75 tokens per English word — holds well enough for plain English prose, but it breaks down fast for anything else. Code tends to tokenize less efficiently than prose because of punctuation, indentation and identifiers. Non-English languages, especially those with non-Latin scripts, often tokenize at a noticeably worse ratio than English on many tokenizers. Numbers, URLs, and unusual formatting (JSON, tables, markdown) all shift the ratio too. If your content isn't plain English sentences, the rule of thumb is a rough sanity check at best, not an estimate to bill against.

Where the surprise usually comes from

  • Structured input — JSON payloads, tool schemas, tables — tokenizes worse than prose of the same character length, and it's easy to forget it's part of the prompt at all.
  • System prompts and tool definitions get resent on every single request; a prompt that looks short in your editor may be large once every tool schema is attached.
  • Output length is harder to predict than input length, and it's priced higher per token on every model in this dataset — see how much does the Claude API cost or how much does the OpenAI API cost for the multiple.
  • Conversation history compounds — a multi-turn chat resends prior turns as input on every new message unless you're explicitly truncating or summarizing it.

Different models, different tokenizers, different counts

It's not just that pricing differs between providers — the token count for the exact same string differs too, because each model family uses its own tokenizer, trained on its own vocabulary. The same paragraph can come out to a meaningfully different token count on one provider's tokenizer versus another's, which means a cost comparison based on "this prompt is roughly N tokens" is only valid for the specific model you counted it against. When comparing cost across providers for the same task, count the same content separately for each candidate model rather than reusing one count everywhere.

How to count accurately

The only reliable method is running your actual content through a tokenizer that matches (or closely approximates) the model you're billing against — different model families use different tokenizers, and the counts do differ between them, sometimes by a meaningful margin on the same text. Paste representative prompts, including the full system prompt and any tool schemas, into the token counter rather than estimating from word count. Do this before you build a cost model, not after you get the first invoice.

The token counter runs entirely client-side against real tokenizer logic — paste a prompt and get an exact count, then carry that number into the calculator to see the dollar cost per model.

A practical workflow

  • Assemble a realistic prompt: system instruction, tool definitions if any, a representative piece of context, and a typical user message.
  • Count it with the token counter to get an exact input token figure — not an estimate.
  • Estimate a realistic output length from a prototype run, or a conservative guess if you don't have one yet.
  • Feed both numbers into the calculator against your candidate models to get an actual per-request and monthly cost.

Five minutes with a real tokenizer beats an afternoon of budget spreadsheets built on a word-count guess. The gap between the two is exactly where most LLM cost surprises come from.

Tokens in, tokens out — and both get logged

Once you're past the estimation stage and into production, the same discipline applies to what you record, not just what you predict. Logging actual input and output token counts per request — not just the resulting dollar figure — makes it possible to trace a cost spike back to its cause: a prompt that grew, a conversation history that stopped being truncated, a model swap that changed the output length. A dollar total alone can't tell you which of those happened; the token counts underneath it can.