1. Home
  2. Blog
  3. Artificial Intelligence

Artificial Intelligence

LLM Tokens Explained: How AI Models Read Text, Count Costs and Fill Context Windows

Language models do not read words or letters. They read tokens. Understanding tokens explains AI pricing, context limits, odd spelling mistakes and why some languages cost more. We ran a real tokenizer to show how it works.

9 min read
LLM tokens explained: how AI models read text, count costs and fill context windows

Key takeaways

  • A token is a chunk of text, often a word or part of a word, that a model maps to a number.
  • In our English sample, 67 words became 74 tokens, about 1.1 tokens per word.
  • The same text can use very different numbers of tokens in different languages and with different tokenizers.
  • The context window and the bill are both measured in tokens, input and output together.

An AI provider charges per million tokens. A model has a “200K context window”. A chatbot cannot count the letters in a word. All three facts make sense once you understand LLM tokens, the units a large language model actually reads and writes.

To show real numbers, we used tiktoken 0.14, the open-source tokenizer library from OpenAI, with its o200k_base and older cl100k_base encodings. Other providers, including Anthropic and Google, use their own tokenizers, so their counts will differ. The principles are the same.

What is a token?

A token is a piece of text from a fixed vocabulary that the model knows, typically containing tens or hundreds of thousands of entries. Common words are often a single token. Rarer words are split into several pieces. Punctuation, spaces and digits are tokens or parts of tokens too.

The model never sees letters. It sees a list of integer IDs. “Hello world” became the IDs [13225, 2375] in our test. Each ID is then turned into a vector of numbers, similar to the embeddings used for search, and the model works with those.

How tokenization works

Most modern models use a method based on byte pair encoding (BPE) or a close relative. During training of the tokenizer, the algorithm starts from single bytes and repeatedly merges the most frequent neighbouring pairs into new tokens. After many merges, common words and word pieces have their own tokens, while unusual strings fall back to smaller pieces. Because it works on bytes, any text, in any language or even binary-looking data, can be encoded.

Tokenizing is a separate step from the model. It happens before the text reaches the model and after the model produces output IDs, which are decoded back into text.

Real examples

'Hello world'      2  ['Hello', ' world']
' Hello'           1  [' Hello']
'tokenization'     2  ['token', 'ization']
'unbelievably'     3  ['un', 'bel', 'ievably']
'Stack Quora'      3  ['Stack', ' Qu', 'ora']
'2026-11-08'       6  ['202', '6', '-', '11', '-', '08']
'1234567'          3  ['123', '456', '7']
'def add(a, b):\n    return a + b'
                   11 ['def', ' add', '(a', ',', ' b', '):\n', '   ', ' return', ' a', ' +', ' b']

A few patterns stand out. The leading space is usually part of the token, so ” world” and “world” are different tokens. Long or rare words, and brand names like ours, are split into pieces. Numbers are broken into groups of up to three digits, which is one reason models can stumble on arithmetic with long numbers. Code is tokenized like any other text, including its indentation.

Rules of thumb

For ordinary English prose, a common estimate is about four characters, or three-quarters of a word, per token. We measured a 67-word paragraph about software testing:

words 67, tokens 74, chars 387
chars/token 5.23, tokens/word 1.1

Our text averaged slightly more characters per token than the usual estimate, since it used many common words. Treat the rule of thumb as a rough guide for planning, and count with the real tokenizer when accuracy matters, for example when checking that a prompt fits a limit. Most providers offer a token-counting tool or API.

Languages and formats cost differently

We tokenized the same refund message in several forms:

Text Characters o200k_base cl100k_base
English sentence 74 14 14
Hindi translation 66 16 66
Japanese translation 24 18 24
JSON object 62 19 19
Short text with emoji 14 9 12

With the older tokenizer, the Hindi sentence needed 66 tokens, more than four times the English version, even though it has fewer characters. The newer tokenizer, with a larger vocabulary, brought it down to 16. This matters in practice: if a model’s tokenizer handles your language poorly, every request costs more, runs slower and fits less text into the context window. Test with your real content, in your users’ languages.

Structured formats have overhead too. JSON’s quotes, braces and keys all use tokens. In our sample, the JSON object needed 19 tokens to hold three short values.

Different models, different tokenizers

Each model family has its own tokenizer, and even one provider’s tokenizer can change between model generations, as the table above shows. So a prompt that is 1,000 tokens for one model may be 1,200 for another. When comparing prices between providers, compare the cost of your actual workload, not just the price per token.

Context windows

The context window is the maximum number of tokens a model can handle in one request. It includes everything: system instructions, the conversation history, any documents you include, tool definitions and the model’s answer. If the total exceeds the limit, the request fails or older content must be dropped.

Context windows have grown dramatically, and many current models accept hundreds of thousands of tokens or more. Check your model’s documentation, because limits change often. A bigger window is not the same as perfect recall, though. Research has found that models can retrieve information from the middle of very long inputs less reliably than from the beginning or end. For large document collections, retrieval-augmented generation (RAG) sends only the relevant passages, which is usually cheaper and more accurate.

Tokens and cost

AI APIs typically charge separately for input tokens and output tokens, with output usually priced higher. Long conversations grow expensive because the whole history is usually sent again with each new message. Many providers also offer prompt caching, which charges less for a repeated prefix such as long fixed instructions. Our model comparison shows how much the choice of model affects cost for the same task.

Tip: Log input and output token counts for every request in your app. The API response normally includes them. Without these numbers you cannot see which feature drives your bill or catch a prompt that has quietly grown.

Quirks that tokens explain

  • Counting letters: “strawberry” was split into ['st', 'raw', 'berry']. The model sees three chunks, not ten letters, so letter-level tasks are harder than they look. Newer models handle many of these better, but the cause is the same.
  • Whitespace: “a b” was 2 tokens, while the same letters separated by six spaces, or by four line breaks, were 3. Messy formatting quietly adds cost.
  • Dates and IDs: “2026-11-08” became 6 tokens. Long identifiers, hashes and URLs can be surprisingly expensive.
  • Output limits: a “maximum tokens” setting cuts the answer off mid-sentence when reached, which is easy to mistake for a model failure.

Practical ways to use fewer tokens

  1. Trim the prompt. Remove repeated instructions and boilerplate. Keep fixed instructions at the start so caching can help.
  2. Send only relevant context. Retrieve the right passages instead of whole documents.
  3. Summarise long histories instead of resending every past message.
  4. Ask for concise output and set a sensible maximum. Output tokens usually cost the most.
  5. Choose compact formats. Short field names and minimal whitespace help when sending structured data.
  6. Use a smaller model for simple tasks such as classification.

Clear, well-structured prompts also tend to need fewer retries, as our prompt engineering guide explains.

Counting tokens in code

A token budget is easy to enforce once you can count. With tiktoken, counting and trimming take a few lines:

import tiktoken
enc = tiktoken.get_encoding("o200k_base")

def count_tokens(text):
    return len(enc.encode(text))

def truncate_to(text, max_tokens):
    return enc.decode(enc.encode(text)[:max_tokens])

doc = ("Refunds are paid within 7 days to the original payment method. "
       "Orders over 1000 rupees ship free.")
print(count_tokens(doc))      # 24
print(truncate_to(doc, 8))    # Refunds are paid within 7 days

Cutting by tokens rather than characters guarantees the result fits, but it can stop mid-sentence, as it did here. In real systems, trim at paragraph or sentence boundaries, and keep the most important content, such as instructions and the user’s question, outside the part you trim. Remember that this counts tokens for one tokenizer only; for other providers’ models, use their counting tools or the usage numbers their APIs return.

Test this logic like any other code. A unit test that feeds an over-long document and checks the result stays under budget will catch the day someone adds a large new instruction block to the prompt.

Final thoughts

Tokens are the currency of language models. They set what fits in a request, what it costs and how fast the answer arrives, and they explain several odd model behaviours. Measure token counts with your model’s own tokenizer, test with your real languages and formats, and treat prompt length as something worth optimising, just like the speed of any other part of your system.

Frequently asked questions

What is a token in an LLM?

A token is a chunk of text, such as a word, part of a word, punctuation or spaces, that the model maps to a number. Models read and generate text as sequences of tokens.

How many words is 1,000 tokens?

For typical English, roughly 700 to 900 words. In our sample, 67 words used 74 tokens. Other languages and code can differ a lot.

What is a context window?

It is the maximum number of tokens a model can process in one request, including the prompt, any documents, the conversation and the model’s response.

Why do some languages use more tokens?

Tokenizers learn from training text, and languages that were less common in it get split into smaller pieces. In our test, an older tokenizer used 66 tokens for a Hindi sentence that took 14 in English.

How can I count tokens?

Use the tokenizer or token-counting tool for your specific model. API responses also report the input and output tokens used by each request.

Keep learning

Work with Stack Quora

Need help with testing, WordPress or SEO?

We help teams ship better software and grow their sites. Tell us what you are working on and we will suggest a clear next step.

Keep reading

More guides on testing, AI & modern development

Enjoyed this article? Pick a topic and jump straight into our newest tutorials.

Artificial Intelligence

LLM Structured Output Explained: Getting Reliable JSON From AI Models

LLM structured output explained with validation we ran in Pydantic: JSON mode and schemas, constrained decoding, the ways model output…

Read article →
DevOps

SSH Keys Explained: How They Work, ssh-keygen, Ed25519 and Safe Habits

SSH keys explained with keys we generated: public vs private keys, ssh-keygen, Ed25519 vs RSA, fingerprints, passphrases, ssh-agent, authorized_keys, config…

Read article →
DevOps

HTTP Caching Explained: Cache-Control, ETag and 304 Responses, With a Live Test

HTTP caching explained with a small server we ran: Cache-Control directives, max-age, no-cache vs no-store, ETag revalidation and 304 responses,…

Read article →
Test Automation

API Contract Testing Explained: Catch Breaking Changes Before They Ship

API contract testing explained with a schema check we ran: what a contract is, consumer-driven contracts, Pact, OpenAPI, which changes…

Read article →
Software Testing

Risk-Based Testing Explained: Score Risks, Build a Matrix and Test What Matters

Risk-based testing explained step by step: identifying risks, scoring likelihood and impact, building a risk matrix, mapping risk to test…

Read article →
Databases & SQL

SQL Constraints Explained: NOT NULL, UNIQUE, CHECK and FOREIGN KEY, Tested

SQL constraints explained with tests we ran: NOT NULL, UNIQUE, CHECK, DEFAULT, PRIMARY and FOREIGN KEY, the NULL loopholes, SQLite's…

Read article →
Databases & SQL

SQL Date Functions Explained: Adding, Comparing and Grouping Dates Without Bugs

SQL date functions explained with queries we ran: adding intervals, month-end surprises, date differences, the BETWEEN trap, grouping by day,…

Read article →
Software Development

Python asyncio Explained: async, await, gather and TaskGroup With Real Timings

Python asyncio explained with code we timed: coroutines, await, gather, TaskGroup, error handling, timeouts, limiting concurrency and the blocking-call mistake…

Read article →
Software Development

Debounce vs Throttle in JavaScript: How They Work, When to Use Each, Tested

Debounce vs throttle in JavaScript explained with timings we measured in Node.js: how each works, simple implementations, leading and trailing…

Read article →
Software Development

Python Context Managers Explained: The with Statement, contextlib and Real Uses

Python context managers explained with code we ran: how with works, __enter__ and __exit__, contextlib.contextmanager, suppress, ExitStack, database transactions and…

Read article →
Artificial Intelligence

LLM Temperature and Top-p Explained: How AI Models Choose Their Next Word

LLM temperature and top-p explained with a simulation we ran: how probabilities are reshaped, what top-p keeps, recommended settings by…

Read article →
DevOps

YAML Explained: Syntax, the Norway Problem and Other Traps We Tested

YAML explained with a parser test: basic syntax, lists and maps, the Norway problem, versions turning into floats, octal zip…

Read article →
DevOps

Cron Jobs Explained: Syntax, Real Schedules and the Mistakes That Break Them

Cron jobs explained with schedules we verified: the five fields, operators, real examples, the day-of-month OR day-of-week trap, environment problems,…

Read article →
Software Testing

Bug Life Cycle in Software Testing: Every Status, Who Owns It and Common Mistakes

The bug life cycle explained: every defect status from New to Closed, who owns each step, rejected, deferred and reopened…

Read article →
Test Automation

Property-Based Testing in Python: Hypothesis Finds the Bugs Your Examples Miss

Property-based testing explained with Hypothesis tests we ran: properties vs examples, strategies, shrinking, the real bugs it found in our…

Read article →
Databases & SQL

SQL Pagination Explained: OFFSET vs Keyset, With a Million-Row Test

SQL pagination explained with a million-row test we ran: LIMIT and OFFSET, why deep pages get slow, keyset (cursor) pagination,…

Read article →
Databases & SQL

SQL EXISTS vs IN: Differences, the NOT IN NULL Trap and Performance

SQL EXISTS vs IN explained with queries we ran: how each works, why NOT IN returns no rows when a…

Read article →
Software Development

Python Logging Explained: Levels, Handlers, Formatters and Mistakes to Avoid

Python logging explained with code we ran: levels, basicConfig quirks, named loggers, handlers and formatters, logger.exception, lazy formatting, duplicate logs…

Read article →
Software Development

JavaScript Map vs Object: Key Differences, Pitfalls and a Benchmark

JavaScript Map vs Object explained with code we ran in Node.js: key types, ordering, the prototype trap, JSON, size, WeakMap…

Read article →
Software Development

Python Type Hints Explained: Annotations, mypy and the Errors It Catches

Python type hints explained with a real mypy run: basic annotations, Optional and unions, TypedDict, Literal, Protocol, generics, Callable, strict…

Read article →
Artificial Intelligence

LLM Tokens Explained: How AI Models Read Text, Count Costs and Fill Context Windows

LLM tokens explained with a tokenizer we ran: how text is split, why counts differ by language and tokenizer, context…

Read article →
DevOps

Semantic Versioning Explained: MAJOR.MINOR.PATCH, Ranges and Release Rules

Semantic versioning explained with code we ran: MAJOR.MINOR.PATCH rules, pre-releases, correct version sorting, caret and tilde ranges, 0.x versions, lockfiles…

Read article →
DevOps

Git Reset vs Revert: How to Undo Commits Safely, With a Tested Example

Git reset vs revert explained with a repository we built: soft, mixed and hard reset, revert commits, reverting merges, recovering…

Read article →
Software Testing

The Test Pyramid Explained: Layers, Ratios and When to Break the Shape

The test pyramid explained: unit, integration and end-to-end layers, sensible ratios, the ice cream cone anti-pattern, the testing trophy and…

Read article →
Test Automation

pytest Fixtures Explained: Scope, yield Teardown, conftest.py and Factories

pytest fixtures explained with a suite we ran: how fixtures work, scopes, yield teardown, conftest.py, factory fixtures, parametrized fixtures, built-ins…

Read article →
Databases & SQL

SQL Upsert Explained: INSERT ON CONFLICT, MERGE and the REPLACE Trap

SQL upsert explained with queries we ran: INSERT ON CONFLICT DO UPDATE and DO NOTHING, the excluded row, conditional updates,…

Read article →
Databases & SQL

SQL LIKE Operator Explained: Wildcards, Case Sensitivity and Performance

The SQL LIKE operator explained with queries we ran: % and _ wildcards, escaping, NOT LIKE and NULL, case sensitivity…

Read article →
Artificial Intelligence

AI Hallucinations Explained: Why Language Models Make Things Up and How to Reduce It

AI hallucinations explained: what they are, why language models produce them, common types, how to reduce them with grounding and…

Read article →
Test Automation

Mocking in Python: unittest.mock, patch and the Mistakes That Make Tests Lie

Mocking in Python with unittest.mock, tested: Mock and return_value, side_effect, patching where a name is used, spec and autospec, mocking…

Read article →
Software Testing

Code Coverage Explained: Line vs Branch Coverage and What 100% Really Means

Code coverage explained with a real coverage.py run: line, branch and condition coverage, reading a report, why 100% coverage can…

Read article →
Artificial Intelligence

What Are AI Agents? How They Work, With a Simple Agent Loop You Can Run

What are AI agents? A plain guide to the agent loop, tools, memory and guardrails, with a small Python loop…

Read article →
Test Automation

TDD vs BDD: Key Differences, One Feature Built Both Ways and When to Use Each

TDD vs BDD explained with one discount feature built both ways: red-green-refactor with code we ran, Given-When-Then scenarios, tools, trade-offs…

Read article →
Software Testing

User Acceptance Testing (UAT): Process, Checklist and Real Examples

User acceptance testing explained: who runs it, how it differs from QA, a seven-step process, a UAT test case template,…

Read article →
Artificial Intelligence

What Are Embeddings? Vectors and Cosine Similarity Explained Simply

What are embeddings? A plain-language guide to vectors, cosine similarity and semantic search, with a small example we ran, common…

Read article →
Test Automation

Flaky Tests: What Causes Them and How to Fix Them for Good

Flaky tests explained with demos we ran: the main causes, how to confirm and diagnose one, proper fixes for timing,…

Read article →
Software Testing

Load Testing vs Stress Testing: Differences, Metrics and k6 Examples

Load testing vs stress testing explained: what each proves, spike and soak tests, the metrics that matter, why averages mislead,…

Read article →