How Big Is a Token? Measuring What Actually Travels on the Wire


Inside a language model, a token has no physical size. It is just an integer ID—a row number like 12847 or 943 pointing into an embedding matrix.

Once generation begins and that token travels toward a client screen, it acquires physical dimensions: characters of human text, bytes of UTF-8 encoding, JSON strings, framing lines, TLS records, and network packets.

How much data does a token actually represent, and how much data has to move across the network to deliver it?

To see the mechanics directly, we measured 10 frontier and open-weight models across 10 tokenizer families using OpenRouter’s streaming API, running 3 passes per model and recording the median of each figure. Three runs (one DeepSeek, two GLM) spent their whole output budget on reasoning and produced no answer text, so those models have fewer usable runs.

Two caveats apply throughout. OpenRouter relays every stream in an OpenAI-compatible format, and several open-weight models were served by third-party hosts (DeepSeek by Decart, GLM and Kimi by Sail Research, Muse by Nebius), so the chunking we saw is what came through that path, not necessarily what each vendor’s native API sends. And sizes use decimal units: 1 kB = 1,000 bytes, 1 MB = 1,000,000 bytes.

Part 1: How big is a token in text?

Before considering networks or protocols, there is the relationship between tokens and human language.

Tokenizers do not split text into fixed-width characters or clean words. They operate on subword vocabularies (usually Byte-Pair Encoding or Unigram) of 32,000 to 256,000 entries. Common English words (water, cycle, surface) are assigned a single token. Rarer words, punctuation, and leading spaces are glued together into pieces.

We prompted each model with identical instructions:

“Write a detailed, plain-English explanation of how the water cycle works, about 600 words, in ordinary paragraphs with no lists or headings.”

Dividing the answer text by the answer tokens (reasoning tokens excluded) yields the core textual size of a token:

Model Tokenizer / Family Characters per token
anthropic/claude-sonnet-5.5 Claude 3.20
z-ai/glm-5.3 GLM 4.77
qwen/qwen3.8-27b Qwen 3 4.81
meta/muse-spark-open Muse 4.84
moonshotai/kimi-k3 Kimi 4.87
mistralai/mistral-large-4-0 Mistral / Tekken 4.94
x-ai/grok-4.7 Grok 4.95
google/gemini-4-argon Gemini 4.97
openai/gpt-6.1-sol o200k-base 5.21
deepseek/deepseek-v4.1-flash DeepSeek 6.01

A few details stand out:

  1. The 5-character baseline: Across eight of the ten model families, English prose falls between 4.77 and 5.21 characters per token. Because English prose is almost entirely ASCII, every character occupies one byte in UTF-8, so bytes per token match characters per token to within 0.01.
  2. Tokenizer granularity: Claude’s tokenizer segments this text into shorter subwords, averaging 3.20 characters per token (and therefore requiring ~1,200 tokens for the same essay). DeepSeek averaged 6.01 characters per token, but its two usable runs disagreed (5.26 and 6.75), so treat that figure as soft.
  3. Language encoding: Outside the Latin alphabet, UTF-8 characters take more bytes: 2 each for Arabic, 3 for Devanagari and most Han characters. In those languages, bytes per token can be significantly higher even when characters per token are low.

At the level of pure language, then, an English token is approximately 5 bytes.

Part 2: What happens when a token is streamed?

When an application streams from an LLM API, it uses Server-Sent Events (SSE) over HTTP. The client does not receive raw token IDs or plain text bytes.

Each chunk arrives wrapped in an SSE data line carrying an OpenAI-compatible JSON structure (abridged here):

data: {"id":"gen-172970...","provider":"OpenAI","model":"openai/gpt-6.1-sol","choices":[{"index":0,"delta":{"content":" precipitation"},"finish_reason":null}]}\n\n

Here, the actual generated content is " precipitation": 14 characters, or 14 bytes of UTF-8. Everything else is envelope.

In our first OpenAI run, events averaged 288 bytes each, and each carried about one token—roughly 5 bytes of text. The delivery envelope is more than 50 times larger than the text it carries.

When tokens arrive one by one, that envelope is repeated for every single token.

Part 3: What travels on the wire?

Beyond the HTTP payload itself, the network adds protocol overhead. If an API server pushes an SSE event immediately, over HTTP/2, each event carries:

  • HTTP/2 DATA frame header: 9 bytes
  • TLS 1.3 record overhead: 22 bytes (5-byte header, 1-byte content type, 16-byte authentication tag)
  • TCP/IPv4 headers with timestamps: 52 bytes

That is 83 bytes of transport framing per event, before Ethernet framing. Over HTTP/1.1, a few bytes of chunked-encoding framing replace the HTTP/2 frame header.

To measure the payload, a small Python script connected to OpenRouter with Accept-Encoding: identity (to observe uncompressed bytes) and counted every byte of the HTTP response body. The wire column adds the 83 bytes per event on top—a worst case that assumes every event travels in its own packet:

Model Usable runs Text B/tok Tokens / event SSE body B/tok Est. wire B/tok Wire expansion
openai/gpt-6.1-sol 3 5.21 0.96 300 B 386 B 74×
meta/muse-spark-open 3 4.84 1.00 366 B 449 B 93×
x-ai/grok-4.7 3 4.95 1.11 240 B 315 B 64×
mistralai/mistral-large-4-0 3 4.94 2.64 138 B 170 B 34×
moonshotai/kimi-k3 3 4.87 3.18 120 B 146 B 30×
qwen/qwen3.8-27b 3 4.81 3.44 110 B 135 B 28×
z-ai/glm-5.3 1 4.77 3.68 106 B 129 B 27×
anthropic/claude-sonnet-5.5 3 3.20 3.86 80 B 101 B 32×
deepseek/deepseek-v4.1-flash 2 6.01 7.98 53 B 63 B 10×
google/gemini-4-argon 3 4.97 41.56 10 B 12 B 2.4×

Text B/tok counts answer tokens only. Tokens per event and the per-token SSE and wire columns count every output token, including streamed reasoning.

The wire figures are an upper bound. For most models the median gap between events was 0.1 ms: events arrive in bursts, and events in a burst can share TLS records and TCP packets.

Part 4: The three streaming regimes

The data shows that “streaming” does not mean the same thing across providers. There are three distinct delivery patterns:

1. One token per event (OpenAI, Muse, Grok)

In gpt-6.1-sol, muse-spark-open, and grok-4.7, tokens per event is between 0.96 and 1.11. OpenAI sends slightly more events than it bills tokens (804 events for 771 tokens in one run), so some events carry less than a whole token.

Every token generated by the model triggers a full JSON serialization and an SSE event.

  • For about 5 bytes of content, the server transmits 240 to 366 bytes of JSON.
  • With transport framing, the wire cost is at most 315 to 449 bytes per token.
  • Wire data is up to 64× to 93× larger than the text itself.
  • In our first OpenAI run, a 771-token answer (about 3.8 kB of text) arrived as 804 events and 235 kB of HTTP body.

2. Micro-batching (Claude, Qwen, GLM, Mistral, Kimi, DeepSeek)

Most providers bundle several tokens into each SSE chunk, from 2.6 to 3.9 tokens per event, and DeepSeek about 8.

In Claude Sonnet 5.5, for example, each event carries 3.86 tokens on average.

  • A ~307-byte event is shared across ~4 tokens instead of 1.
  • SSE body bytes drop to 80 bytes per token.
  • Estimated wire cost drops to at most 101 bytes per token.
  • The model generated about 116 tokens per second. In one run, events arrived on a steady ~33-millisecond beat—about 30 updates per second. In the other two, events mostly arrived back-to-back in bursts, with p90 gaps near 200 milliseconds.

3. Macro-batching (Gemini)

Google’s Gemini 4 Argon uses a completely different transmission cadence: 25 to 49 tokens per event across runs (median 41.56).

Rather than emitting tokens as they are decoded, the stream buffers output into large blocks.

  • In the first run, it delivered 1,496 tokens—615 of them streamed reasoning—in only 36 events.
  • The JSON overhead is diluted across 40+ tokens, dropping the SSE body cost to 10 bytes per token, and total wire cost to at most 12 bytes per token (only 2.4× the raw text).
  • The delivery cadence changes: instead of a continuous stream every few milliseconds, events arrive at median gaps of 410 to 440 milliseconds, with p90 gaps of 510 to 710 ms (and 2.2 s in one run).

Part 5: The scale of reasoning streams

Modern frontier models generate internal reasoning (“thinking”) tokens before emitting visible text.

When an API streams those reasoning tokens (in choice.delta.reasoning), the volume of data traveling across the network shifts by orders of magnitude:

  • In one Qwen 3.8 run, the model generated 9,238 reasoning tokens before outputting 720 tokens of answer text.
  • Over the course of that single request, the client received 2,802 content events (reasoning and answer).
  • The HTTP response body totaled 1,087,129 bytes (1.09 MB).
  • In one Muse Spark run, 3,408 reasoning tokens out of 4,000 expanded the stream to 3,991 events and 1.47 MB of HTTP body.

For a 600-word explanation of the water cycle—which fits in about 3.4 kB of plain text—the network moved over a megabyte of structured streaming frames.

Summary: The layers of a single token

If you trace a single English token through the layers of an inference request, its size depends entirely on where you look:

As a token ID:                      4 or 8 bytes (int32 or int64)
As English text:                    ~4.9 bytes (~4.9 ASCII characters)
As micro-batched SSE (Claude):      ~80 bytes of HTTP body, at most ~101 on the wire
As 1-token-per-event SSE (OpenAI):  ~300 bytes of HTTP body, at most ~386 on the wire

And when the model thinks first, one 600-word answer can take more than 1 MB of HTTP body to deliver.