AI tokens are the units LLMs use to process text. Learn how tokenization works, how to count tokens with tiktoken, and how to reduce token costs.
Every API call to an LLM is measured in tokens. Not words, not characters, not sentences. Tokens. They determine what you pay, how much context fits in a single request, and where your application hits its limits. Understanding what is an AI token is foundational to controlling costs and writing efficient prompts when building on any major LLM provider.
This guide covers how tokenization works under the hood, how to count tokens programmatically, what tokens mean for your API bill, and how semantic caching can cut your token consumption.
Large language models do not process raw text. According to OpenAI's tokenizer documentation, models process text using tokens, which are common sequences of characters found in a set of text. The models learn to understand the statistical relationships between these tokens and excel at producing the next token in a sequence.
A practical rule of thumb from OpenAI's tokenizer page: one token generally corresponds to about 4 characters of common English text. This translates to roughly three-quarters of a word, so 100 tokens equals approximately 75 words.
Tokenization is not intuitive. Common words often map to a single token, but less frequent words get split into multiple tokens. Here is how it plays out in practice:
OpenAI's tokenizer page shows different encodings for different model generations: GPT-5.x and O1/O3 models use one encoding, while GPT-4 and GPT-3.5 (legacy) and GPT-3 (legacy) each use their own. You can experiment with these differences on OpenAI's interactive tokenizer to see exactly how your text splits.
Knowing your token count before making an API call lets you estimate costs, stay within context window limits, and make routing decisions.
OpenAI's tokenizer page recommends their tiktoken package for Python as a programmatic interface for tokenizing text. It runs locally, so there is no network latency and no API cost:
import tiktoken
enc = tiktoken.get_encoding("o200k_base")
tokens = enc.encode("The quick brown fox jumps over the lazy dog.")
print(len(tokens)) # number of tokens
# Get the encoding for a specific model:
enc = tiktoken.encoding_for_model("gpt-4o")For JavaScript, OpenAI notes that the community-supported @dbdq/tiktoken package works with most GPT models.
Beyond local counting with tiktoken, major LLM providers offer server-side token counting endpoints. These are useful when you need an exact count that matches what the provider will bill, especially for requests that include images, tool definitions, or system prompts where local estimation gets tricky.
The pattern is similar across providers: send the same structured input you would send to the generation endpoint, and get back a token count without triggering actual inference.
Every major LLM provider prices API access per million tokens, with separate rates for input (what you send) and output (what the model generates). Output tokens are always more expensive because they require the model to run inference step by step, generating one token at a time.
This pricing structure has three practical implications:
Frontier models can cost 10x or more compared to smaller, faster models. For tasks like classification, extraction, or templated responses, a smaller model at a fraction of the cost often performs just as well.
In a typical chatbot interaction with a few hundred input tokens and a few hundred output tokens, output spend exceeds input spend because of the higher per-token rate.
When you stuff 50,000 tokens of retrieved documents into each prompt, input costs add up fast. At scale, even a small per-token rate becomes significant across thousands of daily queries.
Here is a simple framework for estimating monthly token costs for any LLM feature:
The math is straightforward. The hard part is step 1: most teams underestimate how many tokens their system prompts, tool definitions, and retrieved context actually consume.
The most direct way to cut token costs is to avoid sending duplicate requests. Traditional caching (hash the prompt, store the response) only catches exact matches. Semantic caching goes further.
Consider two prompts: "What is the capital of France?" and "what's the capital of france." These are semantically identical, but a hash-based cache treats them as completely different queries because the strings differ. A semantic cache converts prompts into vector embeddings and compares their meaning, returning the stored response when similarity exceeds a threshold.
When a cached response serves the answer, you skip both input and output token charges entirely. This is different from provider-level prompt caching, which discounts repeated prefixes but still charges for the API call. Semantic caching intercepts the request before it reaches the provider at all.
You can test how this works with different prompts in the shim playground.
Token management is not a single decision. It is a stack of choices that compound:
Tokens are the unit of account for everything in the LLM economy. Knowing how they work, how to count them, and how to spend fewer of them is the difference between an AI feature that scales and one that gets pulled because the bill came in too high.
Use provider prompt caching for repeated input prefixes and an application-managed cache where full-response reuse is appropriate. shim does not add semantic response caching.
const openai = new OpenAI({
baseURL: "https://api.getshim.tech/v1",
apiKey: process.env.SHIM_API_KEY
})