Skip to content
MAMasterAI Now
LLM Internals7 min read

Counting Chat Tokens with Multiple Messages

Learn how chat formatting, speaker labels, and per-message overhead add tokens beyond raw text, with a worked manual counting method and estimation checklist.

By MasterAI Now Team

A chat request costs more tokens than the text you can see because every message is wrapped in structural markup — role markers, separators, and a fixed framing overhead — before the model reads a single word of your content. Those wrapper tokens are generated by the same tokenizer that splits your text, so they consume real context-window space and are billed like any other token. In a multi-message conversation, this overhead repeats per message and often adds up to more than people expect.

Why Chat Tokens Exceed Raw Message Text

A token is the atomic unit a language model processes: roughly a word fragment, often 3–4 characters of English text. A tokenizer is the deterministic program that splits text into those units; each model family has its own. The context window is the maximum number of tokens a model can hold in one request — prompt plus response combined — and it is measured in tokens, not words or characters.

The key point is that the model never receives your messages as plain text. A chat template (the fixed recipe for converting a list of messages into a single token stream) injected special tokens that mark where each message begins and ends, and which role — system, user, or assistant — produced it. These special tokens are entries in the tokenizer's vocabulary reserved for structure, not content. They are invisible in the chat UI but fully present in the tokenized input.

Layer on top of that: the system prompt (instructions set by the application, not typed by you) and the entire conversation history are re-sent with every API request, since the model is stateless and remembers nothing between calls. So the input is not just your newest message but the whole transcript, each turn carrying its own wrapper. That is why the gap between "the words I typed" and "the tokens I'm billed for" grows with conversation length.

Chat Formatting, Speaker Labels, and Per-Message Overhead

Three cost layers sit around your raw text. First, speaker labels and role markers: the template must encode "this next span is a user message" and "this one is an assistant message." Depending on the template, that can be a single special token, a short word like a role name, or both. Second, message delimiters: markers that close one message and open the next, which appear once per message regardless of how short the message is. Third, fixed framing overhead: some templates prepend a start-of-conversation sequence and append an assistant-turn cue at the very end to prompt the reply.

The practical consequence is that overhead is per message, not per conversation. A conversation of ten short messages ("yes," "ok," "try again") pays the wrapper cost ten times while carrying almost no content. This is why trimming turns — or summarizing older history — often saves more tokens than editing wording. The exact overhead is template-specific: treat any figure as an estimate and verify against your provider's documentation or a tokenizer library for your model.

Rough estimation heuristic, stated as an assumption rather than a benchmark:

per_message_overhead ≈ 3 to 5 tokens   (role marker + delimiters)
conversation_framing ≈ 3 to 10 tokens  (fixed start/end sequence)

So for a chat with N messages, an estimate of total tokens looks like:

estimated_tokens ≈ framing + Σ(message_text_tokens) + N × per_message_overhead

The text term usually dominates in long, substantive messages; the overhead term dominates in short, numerous ones.

Worked Example: Counting Tokens Across Three Messages

Assume a model that adds 4 tokens per message for role markers and separators, 3 tokens at the start of the request to prime the reply, and ignores the system prompt. Suppose we send a system prompt plus three turns:

system: You are a helpful assistant.
user:   Summarize the plot of Hamlet.
ai:     A prince seeks revenge after his father is murdered.
user:   Now do it in one sentence.

Token estimates for the raw text (using rough English averages of about 1.3 tokens per word):

system prompt : 5 words  -> ~7 tokens
user msg 1    : 7 words  -> ~9 tokens
ai msg 1      : 9 words  -> ~12 tokens
user msg 2    : 6 words  -> ~8 tokens

Now add structural tokens:

per-message overhead : 4 messages x 4 = 16
request priming      : 3
raw text total       : 7 + 9 + 12 + 8 = 36
estimated total      : 36 + 16 + 3 = 55 tokens

The only content the reader sees is 36 tokens' worth of text, but the request bills roughly 55. The 19 extra tokens are chat formatting, speaker labels, and the priming tokens. Note the system prompt is counted once per request—it is not re-billed per message, but it is re-sent (and re-counted) on every call.

Manual Counting Checklist for Estimating Total Request Tokens

  1. List every message in the request, including the system prompt and all prior turns.
  2. Estimate raw text tokens per message. For English, a plain-word count times roughly 1.3 is a reasonable guess; count numbers, code, and punctuation separately since they often tokenize more heavily.
  3. Add per-message overhead for role markers and separators—commonly a small number like 3 to 5 tokens per message. Treat this as an estimate, not an exact figure.
  4. Add request-level priming tokens once—a handful of tokens at the start of each call, depending on the model format.
  5. Sum the parts:
total ~= (sum of raw text tokens) + (messages x per-message overhead) + priming
  1. Sanity-check: rerun the estimate with a different per-message assumption (e.g., 3 vs 5) and treat the range as your error bar.
  2. For exact counts, feed the fully formatted chat string into the model's tokenizer if you have it; without the tokenizer, manual estimates are best treated as approximations, not guarantees.

Frequently Asked Questions

Why does a chat request use more tokens than the visible message text?

A chat request carries structural scaffolding the user never sees: role markers, delimiter tokens, and per-message framing that tell the model who said what and where each turn begins and ends. Tokens are the subword units a model reads (a word like "counting" might split into "count" + "ing"), and every structural marker is itself made of tokens. So the total billed or counted input is the visible text plus that invisible packaging, which is why the request cost is always somewhat higher than a plain word count suggests.

How much per-message overhead should I add when estimating tokens?

Published tokenizer documentation for common chat models has described a small fixed number of extra tokens per message, on the order of a few tokens each, plus a few tokens to prime the whole conversation. Treat that as a reasoned estimate rather than a guarantee: assume roughly 3–5 tokens per message plus about 3 tokens per conversation as a planning figure, then verify against actual usage numbers if your provider exposes them. For long conversations the per-message overhead accumulates linearly, so it matters more than beginners expect.

Do speaker labels and special tokens count toward the context window?

Yes. The context window is the total budget of tokens a model can attend to in one request, and everything the model actually reads consumes it: your text, the role labels, the delimiter and end-of-turn tokens inserted by the chat template, the system prompt, and prior turns. Nothing that reaches the model is free. The practical consequence is that a conversation "fits" only if the formatted total — not the raw typed text — stays under the limit.

Can I count chat tokens exactly without the model's tokenizer?

Not exactly. Token boundaries depend on the specific tokenizer (the vocabulary and merging rules for that model family), so different models split the same sentence differently, and the chat template's exact special tokens also vary. You can get close with a good approximation — a common rule of thumb for English is about 4 characters per token, or roughly 0.75 words per token — but treat any manual count as an estimate with a margin of error of perhaps 10–20%. For exact figures, run the text through the tokenizer library that matches your model and apply its chat template.

Does system prompt and conversation history count in every API request?

Yes, for stateless chat APIs. Unless the provider explicitly offers server-side conversation state, each request resends the full formatted history — system prompt, every prior user and assistant message, and the new message — so the input token count grows with each turn even though you only typed one new line. This is why long chats get progressively more expensive: turn ten pays for turns one through nine again, plus overhead. Keep an eye on cumulative history size, and trim or summarize old turns when the total approaches the context limit.

Frequently asked questions

Why does a chat request use more tokens than the visible message text?

A chat request carries structural scaffolding the user never sees: role markers, delimiter tokens, and per-message framing that tell the model who said what and where each turn begins and ends. Tokens are the subword units a model reads (a word like "counting" might split into "count" + "ing"), and every structural marker is itself made of tokens. So the total billed or counted input is the visible text plus that invisible packaging, which is why the request cost is always somewhat higher than a plain word count suggests.

How much per-message overhead should I add when estimating tokens?

Published tokenizer documentation for common chat models has described a small fixed number of extra tokens per message, on the order of a few tokens each, plus a few tokens to prime the whole conversation. Treat that as a reasoned estimate rather than a guarantee: assume roughly 3–5 tokens per message plus about 3 tokens per conversation as a planning figure, then verify against actual usage numbers if your provider exposes them. For long conversations the per-message overhead accumulates linearly, so it matters more than beginners expect.

Do speaker labels and special tokens count toward the context window?

Yes. The context window is the total budget of tokens a model can attend to in one request, and everything the model actually reads consumes it: your text, the role labels, the delimiter and end-of-turn tokens inserted by the chat template, the system prompt, and prior turns. Nothing that reaches the model is free. The practical consequence is that a conversation "fits" only if the formatted total — not the raw typed text — stays under the limit.

Can I count chat tokens exactly without the model's tokenizer?

Not exactly. Token boundaries depend on the specific tokenizer (the vocabulary and merging rules for that model family), so different models split the same sentence differently, and the chat template's exact special tokens also vary. You can get close with a good approximation — a common rule of thumb for English is about 4 characters per token, or roughly 0.75 words per token — but treat any manual count as an estimate with a margin of error of perhaps 10–20%. For exact figures, run the text through the tokenizer library that matches your model and apply its chat template.

Does system prompt and conversation history count in every API request?

Yes, for stateless chat APIs. Unless the provider explicitly offers server-side conversation state, each request resends the full formatted history — system prompt, every prior user and assistant message, and the new message — so the input token count grows with each turn even though you only typed one new line. This is why long chats get progressively more expensive: turn ten pays for turns one through nine again, plus overhead. Keep an eye on cumulative history size, and trim or summarize old turns when the total approaches the context limit.