Token estimation

The token counter on the result screen tells you how much of your model's context window the current output will consume. It updates live as files come and go.

How the count is produced

Token counting runs against @dqbd/tiktoken, a WebAssembly build of OpenAI's tokenizer. The encoding is o200k_base, the one o1-preview-2024-09-12 uses, and it is fixed. Claude and Gemini tokenize differently, so for them the count is an approximation.

What gets counted is the whole assembled output, the same string the preview shows and the copy button copies: the XML root or Markdown headings, the per-file tags, the header and the file tree, not only the text of your files. Those wrappers are charged for like everything else. Measured across 60 public repositories on 2026-09-07 they are a median 2.4% of the bundle, and 17.8% on a repository of many small files.

The encoder runs synchronously after the page boots, so toggling files on and off does not introduce a perceptible delay for typical projects.

Above 1 MB the count is sampled

Running the WASM encoder over a multi-megabyte bundle blocks the main thread long enough to feel like the page has frozen. So above 1 MiB of text the count is extrapolated instead of taken. 64 evenly spaced 4 KiB slices are tokenized for real, and the total is scaled by the ratio those slices show. The cost is a flat 256 KiB of tokenizing whatever the bundle's size. The constants live in apps/web/src/lib/tokens-client.ts and the threshold in apps/web/src/lib/tokens.ts.

Before 2026-09-07 this path was Math.ceil(length / 4), an English-prose ratio applied to every language. On the 30 repositories of that 60 repository sample that crossed the threshold, it ran a median 13.5% off. On a repository written in Chinese it ran 62.5% off. Sampling brings the same 30 to a median 0.8% off and 4.5% at worst, all of them within 5% of the true count.

Math.ceil(length / 4) survives in one place only: the fallback when the encoder itself fails to load.

If you want an exact count rather than a sampled one, narrow the output with the filter patterns until the bundle is under 1 MiB.

Model selector

The model selector opens from the model name in the result's fit line, in a sheet beside the cost estimate. The catalog ships with the build and is refreshed at every deploy from models.dev, the same source the cost estimates use.

A few facts that make the picker behave the way it does:

  • Models are sorted by release date descending, so the newest Claude, GPT, Gemini, and so on appear at the top.
  • The picker shows the canonical model (e.g. claude-sonnet-4-6) and a via {provider} hint. The hint names the cheapest priced provider that offers that model on the day of the deploy. If the cheapest provider changes between deploys, the hint changes; the canonical id stays the same so your selection survives.
  • The selected model's identifier is the catalog UID (lab/model-id), persisted in localStorage. Models removed from the catalog upstream are pruned at load time.

See also

  • Token costs for which toggles cost or save tokens.
  • Filter precedence for the layered filtering pipeline that decides which files contribute to the count.
  • How many tokens is a codebase? for the 60 repository measurement the figures above come from, and what a whole repository costs to send.
  • Context window costs for what filling 100K, 500K or 1M tokens costs across every model in the catalogue.