jsonlkit.com
JSONL (JSON Lines) utilities, in the browser
Say hi →

Count Tokens in a JSONL Dataset (GPT, Claude, Llama)

updated 16 May 2026

JSONL token counter. Estimate tokens per record and total fine-tune cost across a JSONL (JSON Lines) file. Pick a model (GPT-4o, Claude, Gemini, Llama). Flags records over the context window. Browser-only.

100% client-side. No upload.

Count tokens

Drop a .jsonl file here, or
Per-record token counts

JSONL Token Counter

Estimate token totals and per-record token counts across a JSONL file, with a model picker and fine-tune cost estimate. Flags records that exceed the chosen model's context window before you waste a training run on them.

What is counted

The conversation, not the JSON around it. Each line is parsed, the message contents are pulled out — messages[] for OpenAI and Anthropic records, a top-level system, Gemini's contents[], or a prompt/completion pair — and those are what get counted, plus the framing every provider adds per message (three tokens each, and three to prime the reply). Braces, quotes and key names are not billed, and counting them inflates a short chat record by a third. The summary shows what the raw-JSON count would have been so you can see the difference; a record whose shape is not recognised falls back to it, and says so.

How the estimate works

Real tokenizers (OpenAI's tiktoken, Anthropic's) mean shipping a couple of megabytes of WASM to the browser. Instead the text is segmented the way a byte-pair encoder segments it: words carry their leading space, a long word breaks into pieces of about five characters, digits break into runs of three, runs of punctuation merge, and each CJK character is its own token. That is much closer than dividing the character count by four, which is only right for ordinary English prose and badly wrong for code, identifiers and numbers.

On plain English it lands on the exact tiktoken count for most sentences. On dense punctuation it runs a little high, and on non-Latin scripts and emoji it runs low. A per-model factor adjusts for the family — Claude's tokenizer splits somewhat more aggressively than OpenAI's. Treat the result as an estimate good to a few per cent for budgeting, not as an invoice.

Fine-tune cost estimate

The cost row is tokens × epochs × $ per 1M. Put the current price in the Price box and it uses that; leave it empty and it falls back to the figure below for the selected model. Prices move, and a hard-coded number in a tool you visited once is exactly the kind of thing that turns into a wrong budget — so check the provider's page and type it in.

For models with no published training price the row asks for one rather than inventing it.

Context-window check

Each model's per-request context window is fixed (e.g., 128k for GPT-4o, 200k for Claude). Records longer than that will fail at training or inference time. The summary flags how many records in your file exceed the limit so you can split or trim them before submitting — the JSONL Splitter won't help here (records stay intact), but the JSONL Viewer can help you find the long ones.

Tips & common pitfalls

Example

Input — a small fine-tune dataset:

{"messages":[{"role":"user","content":"Hi"},{"role":"assistant","content":"Hello!"}]}
{"messages":[{"role":"user","content":"What is 2+2?"},{"role":"assistant","content":"4."}]}

At 3 epochs on GPT-4o mini, the summary will show ~50 tokens × 3 = 150 training tokens, costing fractions of a cent. Real datasets are millions of tokens; the estimate scales linearly.

Frequently asked questions

Why not use the real tokenizer?

It's a tradeoff. The real tokenizer is more accurate but adds ~2 MB of WASM to download. For budgeting fine-tunes the estimate is close enough — within a few percent on English chat data — and the tool stays instant on big files.

Does this work for inference cost (input/output token billing)?

Not directly — fine-tune training pricing and inference pricing differ. This tool focuses on training. For inference cost, multiply the input-token total by the published per-million input price for the model.

Why don't all Claude / GPT-4 Turbo entries show a price?

Anthropic doesn't publish a self-serve fine-tune price for Claude as of the date on this page; GPT-4 Turbo's fine-tune isn't generally available. Rather than make up numbers, those rows show "—".

Is my data sent to a server?

Never. Counting happens in your browser. See the privacy policy.

Related tools