n4nAI

Token counting libraries for Claude, GPT-4o, and Gemini

A engineer-focused list of token counting libraries by model for Claude, GPT-4o, and Gemini, with code samples and a unified dispatcher pattern.

n4n Team3 min read644 words

Audio narration

Coming soon — every post will get a voice note here.

Estimating cost before sending a request is table stakes when you’re shipping LLM features. The right token counting libraries by model save you from surprise bills and truncated context windows. Below we break down the practical options for Claude, GPT-4o, and Gemini, with code you can drop into a service today.

1. tiktoken for GPT-4o and OpenAI models

tiktoken is the reference tokenizer released by OpenAI. GPT-4o uses the o200k_base encoding, which you load directly by name or via encoding_for_model("gpt-4o"). It’s a Rust binary with Python and Node bindings, so counting a 100k-token document takes single-digit milliseconds on a laptop.

import tiktoken
enc = tiktoken.get_encoding("o200k_base")
# or enc = tiktoken.encoding_for_model("gpt-4o")
tokens = enc.encode("Your prompt for GPT-4o")
print(len(tokens))

In a Node service, install the tiktoken npm package and call getEncoding("o200k_base"). The API is nearly identical. This library does not support Claude or Gemini; forcing it on non-OpenAI text will undercount because vocabularies differ.

A subtle point: tiktoken counts the raw string. OpenAI’s chat completions endpoint adds invisible overhead for role markers and the conversation template. For GPT-4o, budget roughly 3 extra tokens per message and 3 per reply start. If you need exact figures, log the usage field from the API response and calibrate.

The token counting libraries by model conversation starts here because OpenAI is the only vendor that open-sourced its production tokenizer. Use it unconditionally for any GPT-4o path.

2. @anthropic-ai/tokenizer for Claude

Anthropic maintains an official tokenizer as a Rust crate with WASM bindings. The @anthropic-ai/tokenizer npm package is the most accurate client-side counter for Claude text. It mirrors the server’s SentencePiece-style vocabulary, including the quirks around whitespace and code fences.

import { countTokens } from "@anthropic-ai/tokenizer";

const text = "Hello Claude, count me accurately.";
const count = countTokens(text);
console.log(count);

For Python shops, the Anthropic SDK added a messages.count_tokens RPC. It is an API call, not a local computation, but it guarantees parity with the billing system.

from anthropic import Anthropic
client = Anthropic()
resp = client.messages.count_tokens(
    model="claude-3-5-sonnet-20240620",
    messages=[{"role": "user", "content": "Hello"}]
)
print(resp.input_tokens)

Note that Claude bills image tokens based on resolution and placement; the text tokenizer ignores images. If your request mixes modalities, call the API counter rather than the local lib. The token counting libraries by model fragment exactly at this boundary: text-only local, multimodal remote.

3. google-generativeai for Gemini

Gemini’s tokenizer is proprietary, but Google exposes a countTokens method in the official SDKs. The Python google-generativeai package wraps the REST RPC and returns a total_tokens field without consuming generation quota.

import google.generativeai as genai
model = genai.GenerativeModel("gemini-1.5-pro")
result = model.count_tokens("Explain token counting.")
print(result.total_tokens)

The JS SDK @google/generative-ai provides the same:

import { GoogleGenerativeAI } from "@google/generative-ai";
const genai = new GoogleGenerativeAI(process.env.API_KEY!);
const model = genai.getGenerativeModel({ model: "gemini-1.5-pro" });
const { totalTokens } = await model.countTokens("Explain token counting.");
console.log(totalTokens);

These calls hit Google’s servers, so they are not offline. For pure local approximation, load the Gemma 2B SentencePiece tokenizer from HuggingFace; Gemini shares architectural lineage, but expect drift on non-English and rare symbols. The token counting libraries by model for Gemini are therefore “exact via API, approximate via Gemma.”

4. HuggingFace transformers as a fallback

When you cannot reach a vendor API and need a rough estimate, transformers with an open SentencePiece model is the only game in town. For Gemini-adjacent work, google/gemma-2b is the closest public proxy.

from transformers import AutoTokenizer
tok = AutoTokenizer.from_pretrained("google/gemma-2b")
ids = tok("Approximate Gemini tokens", add_special_tokens=False)
print(len(ids))

For Claude there is no sanctioned open tokenizer; community replicas exist but diverge on whitespace handling and code tokens. Treat their output as ±5% at best. This is the gray area of token counting libraries by model: vendor-exact versus open-approximate.

If you route through a gateway like n4n.ai, per-token usage metering arrives in the response headers, so post-hoc counts are authoritative. Local libraries still earn their keep by letting you reject oversized prompts before they traverse the network.

5. A unified dispatcher wrapper

No single package covers all three vendors, so production code usually hides them behind a small function. Cache the encoding objects, branch on model prefix, and surface a single integer.

def count_tokens(model: str, text: str) -> int:
    if model.startswith("gpt-4o") or model.startswith("gpt-"):
        import tiktoken
        return len(tiktoken.get_encoding("o200k_base").encode(text))
    elif model.startswith("claude"):
        from anthropic import Anthropic
        return Anthropic().messages.count_tokens(
            model=model, messages=[{"role": "user", "content": text}]
        ).input_tokens
    elif model.startswith("gemini"):
        import google.generativeai as genai
        return genai.GenerativeModel(model).count_tokens(text).total_tokens
    else:
        raise ValueError(f"no counter for {model}")

Add @lru_cache on the tiktoken encoding and reuse a singleton Anthropic/Google client. The token counting libraries by model become swappable adapters, and your business logic stays clean.

Summary table

Model Library Local? Accuracy
GPT-4o tiktoken Yes Exact
Claude @anthropic-ai/tokenizer (JS) / SDK (Py) JS local, Py API Exact
Gemini google-generativeai API Exact
Any transformers (Gemma) Yes Approx ±5%

Pick vendor-native counters where you can; reserve approximations for dashboards and logs. The fragmentation is annoying but manageable with a thin wrapper.

Tagstoken-countingclaudegpt-4ogemini

Written by

n4n Team

The team building n4n — a single OpenAI-compatible API in front of 240+ models, with automatic fallback, load balancing and pay-per-token metering.

More from n4n Team →

All token counting & cost estimation libraries posts →