LLM Token Counter
Counting the tokens in a block of text is the easy half. The half that decides your bill is knowing which text gets counted again on the next turn, and the next, and the one after that. A chatbot does not pay for a document. It pays for a turn, and every turn carries the system prompt, the tool schemas, whatever the retriever pulled in, and the entire conversation so far. This tool does both jobs: paste text for a straight count, or switch to turn budget and watch a six-turn conversation bill more than you assumed.
Count tokens, then find out where they go
Paste text for a straight count, or switch to turn budget to see what a whole conversation bills once the system prompt, the tool schemas and the growing history are charged on every turn. Everything runs in your browser, so a production prompt never leaves your machine.
The current OpenAI generation — GPT-4o, GPT-4o mini, GPT-4.1 and GPT-5 all share this encoder. Counts here are estimates, not exact encodings: mean absolute error is 8.4% against real tiktoken on the 31 held-out samples of our calibration corpus, with the full per-content-type breakdown, including the direction each category leans, published further down this page.
Estimated tokens
62
Characters
302
| Words | 52 |
| Characters without spaces | 251 |
| Characters per token | 4.87 |
| Tokens per word | 1.19 |
| o200k_base (GPT-4o, 4.1, 5) | 62 |
| cl100k_base (GPT-4, 3.5) | 62 |
Need an exact count for a hard context limit? Use the vendor's own tokenizer. This estimator is built for budgeting, where a few percent does not change a decision and where pasting a production prompt into somebody else's web form is the real problem.
Embed this tool on your site (free)
<iframe
src="https://chatbotscape.com/embed/tools/llm-token-counter/"
width="100%" height="1400" frameborder="0"
title="LLM Token Counter by Chatbotscape"
loading="lazy">
</iframe>What a token is, briefly
A token is a chunk of text a language model treats as one unit. It is usually a common word, part of a longer word, a punctuation cluster, or a run of digits. The familiar rule of thumb is four characters per token. Across the 29 English samples in our calibration corpus, measured with the real encoder rather than estimated, the figure ranged from 3.4 to 7.3 with a median of 4.7. Averages hide a lot at this granularity, and the exceptions are where the money is: tiktoken splits get_order_status into three tokens rather than five, because each underscore is absorbed by the word after it, while 2026-08-04 costs six, because digits break every three characters and each hyphen stands alone.
Models bill input tokens and output tokens separately, and input is where a chatbot spends the overwhelming majority of its budget. That asymmetry is the reason this page exists. Output is bounded by how much the bot says. Input is bounded by nothing except what you chose to resend.
Why a chatbot turn costs more than the message in it
Language model APIs are stateless. The model does not remember the previous turn, so every request has to carry the whole conversation with it. On turn six, you are paying for turns one through five again, plus the system prompt again, plus the tool definitions again, plus whatever your retriever pulled in this time.
Load the turn budget tab and you get our default scenario: a retrieval-backed support bot with a 115-token system prompt, two function schemas at 151 tokens, 3 retrieved chunks of 320 tokens each, 40-token customer messages and 110-token replies, 6 turns per conversation, 40,000 conversations a month. Every figure in this section is computed from exactly those settings, so you can change one in the tool and watch the conclusion move.
Turn one bills 1,272 input tokens. Turn 6 bills 2,052, about 1.6x the first. The whole conversation bills 9,972 against 7,632 for the same conversation if history were free. That is a 1.31x multiple, and it is the smaller of the two findings on the screen.
The bigger finding: 74% of that bill is text you already sent
In the default scenario, the system prompt, the tool schemas and the retrieved chunks account for 73.8% of every input token billed across the conversation. Not because any of them is unusually long, but because all of them are resent, unchanged, on all 6 turns. The retrieved chunks alone are 57.8% of the bill.
This inverts the usual advice. Teams reach first for history trimming, because that is the lever every framework exposes. Switch the default scenario to a sliding window of the last 3 turns and the conversation drops from 9,972 to 9,504 input tokens: a 4.7%saving for a change that measurably degrades the bot's memory. Drop one of the 3 retrieved chunks instead and you save 1,920 tokens per conversation, 19.3% of the bill and 4 times what the window bought, with no effect on whether the bot remembers what the customer said two turns ago.
The opposite case is just as sharp, which is why the tool asks for your numbers rather than printing a rule. Take a lean bot: no retrieval, no tool schemas, a 120-token prompt, ten turns of ordinary back-and-forth, everything else unchanged. Now history is 80.9% of the bill and the replay multiple is 5.23x. Same arithmetic, opposite conclusion. Whether trimming history is the best move available to you depends entirely on what else is riding along on each turn, and that is not something a blog post can tell you.
Where the tokens go, in order of how often people miss them
Tool and function schemas
The most reliably overlooked line. Function definitions are sent in full on every turn, whether or not a tool is called, and JSON schemas are dense: descriptions, enums, nested property objects, required arrays. Two modest functions in the default scenario cost 151 tokens a turn, more than the 115-token system prompt sitting beside them. A bot with fifteen registered tools is often carrying more schema than instruction. If some tools only apply to a few intents, attach them conditionally instead of globally. Platforms that speak MCP make this easier, because the tool surface is negotiated per session rather than hard-wired into every request.
Retrieved chunks
Retrieval is sold as the cheap alternative to a bigger model, and it is, but the cost does not vanish. It moves from the model tier to the context length. Passing the top five chunks instead of the top three feels free at design time and costs you on every turn thereafter. Both dials matter: how many chunks, and how long each one is. Our RAG chatbot guide covers chunk sizing, and semantic search for a knowledge base covers getting the right three rather than the top five.
The system prompt nobody owns
Prompts accumulate. Someone adds a paragraph on tone, someone else pastes in four example refund replies, a third person appends the escalation matrix after a complaint. Nothing gets removed, because removing it feels risky and the file has no owner. Few-shot examples are the usual dead weight: they were added to fix behaviour that a later model handles natively, and they are billed on every turn forever. The tool prices this directly. In the default scenario above, 100 tokens cut from the prompt is 24.0M input tokens a month, which is just 100 tokens times 6 turns times 40,000 conversations. Prompt engineering for chatbots covers what is safe to cut.
Per-message wrapper overhead
Each message in a chat request carries a few tokens of structure for its role and delimiters. OpenAI's own reference token counter charges three tokens per message for every current model, plus three once per request to prime the reply, and the tool defaults to exactly that. Trivially small per message, and not small at all across twelve messages a conversation multiplied by your monthly volume. It is included so that your estimate reconciles against your invoice instead of landing a few percent under it for no visible reason.
Worth knowing if you inherited an older estimate: the retired gpt-3.5-turbo-0301 charged four per message rather than three, and that stale constant still circulates in blog posts and internal spreadsheets. Both values are editable in the tool if you are reconciling against something specific.
How accurate is the estimate?
The honest answer, with the measurements attached. This tool does not ship a real byte-pair-encoding vocabulary, because doing so means downloading a multi-megabyte table before the page can count anything. It uses a character-class estimator instead, and we calibrated it against the genuine article.
The corpus is 63 samples of the text this audience actually measures: system prompts, knowledge-base chunks, JSON tool schemas, customer messages, bot replies, code, markdown, order IDs and money, four Western European languages, and five non-Latin scripts. Ground truth came from running tiktoken 0.13.0, encodings o200k_base and cl100k_base over the same corpus, on 4 August 2026. Constants were fitted on 32 samples and validated against 31 held-out samples written afterwards.
The number to hold us to is the held-out one: 8.4% mean absolute error on o200k_base and 8.8% on cl100k_base, across the 31 samples the constants never saw. The table below pools all 63 samples and therefore reads slightly better, at 7.7% and 7.8%. Both are published because the pooled figure is the one that breaks down usefully by content type, and the held-out figure is the one that is honest about text the estimator has never seen.
| Content type | Samples | Mean absolute error | Signed bias |
|---|---|---|---|
| English prose, prompts and replies | 29 | 6.9% / 5.4% | +3.3% / +1.7% |
| JSON tool schemas and code | 8 | 6.3% / 4.9% | +0.8% / +3.7% |
| Markdown, IDs, dates and money | 8 | 10.3% / 10.2% | +4.4% / +3.9% |
| Spanish and French | 4 | 6.6% / 16.1% | -5.1% / -15.5% |
| Portuguese and German | 4 | 17.5% / 28.8% | -17.4% / -28.9% |
| Cyrillic | 2 | 2.7% / 2.3% | +2.7% / -2.4% |
| Chinese and Japanese | 4 | 8.3% / 4.7% | -5.8% / +1.0% |
| Arabic and Devanagari | 4 | 3.9% / 1.8% | -1.4% / -0.8% |
| All samples (pooled) | 63 | 7.7% / 7.8% | +1.2% / -0.3% |
| Held-out only | 31 | 8.4% / 8.8% | — |
Every cell reads o200k_base / cl100k_base. Mean absolute error is how far off a typical single estimate is. Signed bias is which way the errors lean once pooled, and it is the column that decides whether a correction is worth applying.
Read the table for the row that matches your content, not for the bottom line. On held-out samples, 65% land within 10% of the true count on o200k_base and 77% within 15%; pooling the fitted samples in lifts those to 70% and 84%. Most categories are noisy rather than skewed, and the distinction is what the two column pairs are for: English prose is off by 6.9% on a typical sample but leans only +3.3% in aggregate, so errors largely cancel across a realistic body of text and no correction is worth applying.
Two rows behave differently, and they are the ones to act on. The estimator runs consistently low on Portuguese and German (bias -17.4% on the current encoder, -28.9% on the older one) and, less severely, on Spanish and French (-5.1% and -15.5%). Those languages fragment more than an English-tuned length curve expects, and they fragment the same way every time rather than randomly. Per language on the current encoder the bias runs Spanish -2.9%, French -7.9%, Portuguese -14%, German -21.3%, so if you are budgeting for one of them specifically, use its own number rather than the row average.
One correction is buried inside an otherwise reassuring row and deserves calling out, because averaging hid it in an earlier version of this table. The Chinese and Japanese row reads a mild -5.8% on the current encoder, but that is two languages cancelling: Japanese is +2.6% while Chinese alone is -14.3%, a larger underestimate than any European row. If you are budgeting a Chinese-language bot on a current model, add about 15%.
Two caveats on all of that, because the sample counts are small. The per-language rows rest on 2 samples each, which is enough to see a consistent direction and not enough to pin the magnitude. And these corrections belong only to the rows that show a real one-directional lean. Applying a blanket percentage to the rows where bias is near zero would push roughly half your estimates further from the truth than leaving them alone.
For budgeting, this is comfortably good enough. An 8% error does not change whether you trim the prompt or drop a chunk, because the gaps between those options run to tens of percent, as the default scenario above shows. For a hard context-window limit it is not good enough, and you should use the vendor tokenizer. What this tool gives you that a vendor tokenizer does not is the second tab, and the fact that a production system prompt never leaves your browser to get counted.
Two things keep this section honest rather than merely well-intentioned. First, the whole calibration corpus ships with the site: all 63 samples and their true token counts under both encoders, marked fitted or held-out, sitting in a JSON fixture next to the estimator. Second, a verification script re-runs the shipped estimator over that fixture on every build, recomputes every figure in the table above, and fails the build if any of them has moved by more than a rounding step. Retune a constant without updating the page and the deploy stops.
That check is not decoration. It caught a real error while this page was being written: the split had been described as 31 fitted and 32 held-out when the fixture actually contains 32 and 31. A hand-maintained accuracy table drifts from the code it describes, quietly and quickly, which is exactly the failure mode that makes published error bars worth ignoring.
Which encoder applies to which model
o200k_base is the current OpenAI generation: GPT-4o, GPT-4o mini, GPT-4.1 and GPT-5. cl100k_base is the previous one: GPT-4, GPT-4 Turbo, GPT-3.5 Turbo, and the text-embedding-3 models. For pure English the two are structurally almost identical and the tool will show you near-identical counts. For everything else the gap is large.
We ran one paragraph of ordinary support-desk copy through both encoders in six languages to size it. English came out identical at 31 tokens either way. Every other language cost between 1.65x and 3.77x more on the older encoder for precisely the same sentence.
| Same paragraph in | o200k_base | cl100k_base | Older encoder costs |
|---|---|---|---|
| English | 31 | 31 | 1.00x |
| Chinese | 26 | 43 | 1.65x |
| Korean | 39 | 83 | 2.13x |
| Russian | 41 | 103 | 2.51x |
| Arabic | 39 | 110 | 2.82x |
| Hindi | 47 | 177 | 3.77x |
Measured 4 August 2026. Source: tiktoken 0.13.0, exact encoder output for one paragraph describing round-the-clock support hours, translated into each language. These are exact encoder counts, not output from this page's estimator. The estimator's per-script constants come from a separate density measurement over long-form prose in each script, and are built so that the ratio between the two encoders carries through rather than being fitted away. On short or mixed text the estimator will report a smaller gap than this table shows, because it charges whole tokens per word and that rounding compresses the ratio. Treat the table as the long-run truth and the tool as an approximation of it. One gap worth naming: Korean has no sample in the calibration corpus, so its accuracy is inferred from this probe rather than measured end-to-end like the other scripts.
The practical reading: a multilingual bot got materially cheaper to run when OpenAI changed encoder generations, and nobody had to rewrite a prompt for it. Any token budget you inherited from a GPT-3.5 deployment is badly wrong for a non-English bot on a current model, in your favour. Note the asymmetry that survives, though. On the current encoder that Hindi paragraph still costs about 1.5x its English equivalent, so per-language cost differences have narrowed rather than disappeared, and a bot serving Hindi and English on the same plan is still not serving them at the same cost.
Anthropic's Claude models and Google's Gemini use their own tokenizers, which are not the ones this page implements, so we do not offer a Claude or Gemini setting rather than publish a number we cannot verify. English text is broadly comparable across all of them; anything else is not, and their official counters are the place to check. If you are choosing between model providers rather than budgeting for one, our bring-your-own-LLM guide covers what changes when you swap the model underneath a chatbot platform.
What to do with the number
Take the monthly input and output totals to the LLM API cost calculator for a price across providers, or the OpenAI pricing calculator if you have already settled on OpenAI. This page carries no price table on purpose. Token prices move, and a calculator that quietly goes stale is worse than one that sends you somewhere current.
Model cost is one line in a larger sum. The platform fee, the human agents handling everything the bot escalates, and the build itself usually dominate it. The bot vs human cost calculator puts model cost next to agent cost, and pricing an AI chatbot walks through the three commercial models vendors use to charge you for all of it.
What this tool deliberately is not
It is not a tokenizer. It does not show you token boundaries or IDs, it will not reproduce a vendor count exactly, and it should not be used to check that a prompt fits under a hard limit with two tokens to spare. It is a budgeting instrument, built to a precision that matches the decisions people actually make with token counts: keep three chunks or five, cut the examples out of the prompt or leave them, window the history or do not. Those choices turn on tens of percent, not on single tokens.
It also does not price anything. No token prices, no model tiers, no monthly bill in dollars. That is a deliberate scope line: the arithmetic on this page is stable, and price tables are not.
And it does not cover every model family. The estimator implements the two OpenAI encoder generations and nothing else, because those are the two we can check against a public reference implementation. Where we could not verify something, we have said so rather than filled the gap.
Related Chatbotscape tools and resources
- LLM API cost calculator — turn the token totals from this page into a monthly bill across providers
- OpenAI API pricing calculator — the same job for a single provider, with caching and batch discounts
- Bot vs human cost calculator — model cost next to agent cost, so the comparison is honest
- Context window — the ceiling this page measures you against
- System prompt — the line item you can cut today
- Retrieval-augmented generation — where the chunk tokens come from
- How to build a RAG chatbot — chunk sizing and retrieval depth
- Prompt engineering for chatbots — what is safe to delete from a prompt
- Botpress review — a platform that exposes the token bill per conversation
- Chatbase review — retrieval-first architecture, so chunk sizing is the cost lever
FAQ
How do I count tokens for GPT-4o or GPT-5?
Paste the text into the counter above with the encoder set to o200k_base, which is what GPT-4o, GPT-4o mini, GPT-4.1 and GPT-5 all use. The count is an estimate carrying 8.4% mean absolute error against the real encoder on held-out samples. For a budget that is more than sufficient; for a hard context-window check, use OpenAI's own tokenizer.
How many tokens is 1,000 words?
About 1,160 for ordinary English prose on the current encoder. That is our own measurement against the real encoder rather than the commonly repeated 1,300 to 1,400: across all 29 English samples in our corpus the ratio ran from 1.00 to 1.54 tokens per word, median 1.16. The spread is the useful part. Short conversational customer messages sit near 1.14 and long-form knowledge-base prose near 1.13, while JSON schemas and code leave the scale entirely at a median of 4.34 tokens per word, because most of what they contain is punctuation rather than words. Paste a real sample rather than trusting any ratio; the counter reports your actual tokens-per-word so you can see where your own text falls.
Why is my API bill higher than my token count suggests?
Almost always because you counted the message and paid for the conversation. Every turn resends the system prompt, the tool schemas, the retrieved chunks and all previous messages, so a six-turn conversation bills six copies of everything fixed plus a growing history. The turn budget tab reconstructs that arithmetic. The other common gap is per-message overhead: OpenAI's reference counter charges three tokens per message plus three per request, both of which the tool includes by default.
Does trimming conversation history save much?
It depends on what else rides along on each turn, which is exactly why this tool asks. For a retrieval-heavy bot with a long prompt, history is often under a quarter of the bill and a sliding window saves a few percent while costing the bot its memory. For a lean bot with no retrieval and no tools, history can be over 80% of the bill and a window is the single best change available. Enter your own numbers and read the two shares before you change anything.
Are tool and function definitions billed on every turn?
Yes, in full, whether or not a tool is called. This surprises people more than any other line on the page, because the schemas are configuration rather than content and do not feel like they should be charged repeatedly. Paste yours into the tool schema box to see what they cost you per turn.
Do Claude and Gemini count tokens the same way?
No. They use different tokenizers, so a count from this page is a GPT-family count. English text is broadly comparable across the major families; anything else can diverge considerably. We do not publish a Claude or Gemini multiplier here because we cannot verify one, and their official counters are the correct place to check.
Does the counter send my prompt anywhere?
No. All estimation runs in your browser as you type, and the text you type is never transmitted, stored or logged. Refreshing the page clears it. That is the main reason this is an estimator rather than a server call: production system prompts are exactly the kind of thing that should not be pasted into somebody else's web form. To be precise about scope, the site as a whole runs standard page-level analytics like any other site; what that never sees is the contents of these boxes, because the contents never leave the page.
Can I embed this tool on my site?
Yes, free. Copy the iframe snippet from the embed section above. The embed strips Chatbotscape navigation and keeps the tool plus attribution.