aillmjsonperformance

Cut LLM Token Costs by Optimizing Your JSON

·8 min read·AI & JSON

JSON is a hidden line item on your AI bill

When you send JSON context to a model — retrieved documents, tool results, examples — every brace, quote, and space is tokenized and billed. The same is true for JSON the model returns. For high-volume applications, the structure of your JSON can swing token costs by 20–40%, which is real money at scale.

Where the tokens go

Tokenizers treat JSON punctuation and repeated keys as tokens. A 50-row array where every object repeats "first_name", "last_name", and "email_address" spends a surprising share of its budget on key names you already know.

Tactic 1: Minify before sending

Pretty-printed JSON is for humans. Models do not need indentation. Minifying removes whitespace and newlines:

json
{
  "user": {
    "name": "Ada",
    "active": true
  }
}

becomes

json
{"user":{"name":"Ada","active":true}}

That is a meaningful reduction on large payloads, and it changes nothing about the data. Minify any JSON you inject into a prompt.

Tactic 2: Shorten or drop redundant keys

If you control the shape, trade verbose keys for short ones in the model-facing payload and map them back in code:

json
[{"n":"Ada","r":"admin"},{"n":"Linus","r":"user"}]

For tabular data, a header-plus-rows layout removes repeated keys entirely:

json
{"cols":["name","role"],"rows":[["Ada","admin"],["Linus","user"]]}

On a 100-row table this can cut the payload dramatically because each key appears once instead of 100 times.

Tactic 3: Send only what the model needs

The cheapest token is the one you never send. Before injecting a record, strip fields the task does not use — internal IDs, timestamps, audit metadata, null fields. A focused payload is both cheaper and more accurate, because irrelevant data distracts the model.

Tactic 4: Constrain the output shape

Models are verbose by default. A tight output schema with short field names reduces completion tokens. Asking for {"s":"pos","c":0.9} instead of a paragraph of analysis plus JSON saves on every single call.

Tactic 5: Cache stable context

If you send the same large JSON context on many calls (a product catalog, a policy document), use the provider's prompt caching so the repeated prefix is billed at a reduced rate after the first call. Keep the cached block stable and put the variable part at the end.

Measuring the impact

Always measure before and after. Token counts are not linearly related to character counts, so estimate with the provider's tokenizer. A quick before/after on a representative payload tells you whether an optimization is worth the added complexity.

OptimizationTypical savingEffort
Minify whitespace5–15%Trivial
Drop unused fields10–30%Low
Header + rows for tables20–40% on big tablesMedium
Prompt cachingUp to 90% on the cached prefixMedium

Don't over-optimize

Readability still matters for prompts you debug by hand, and aggressive key-shortening can confuse the model if names become meaningless. Optimize the high-volume, machine-only paths; leave low-volume, human-edited prompts readable.

Frequently asked questions

No. Whitespace carries no information for the model. Minify freely.

Sometimes. "qty" is fine; "q" may be ambiguous. Keep keys short but still meaningful, and document the mapping in code.

Use the provider's tokenizer library (for example tiktoken for OpenAI-style models) to count tokens on a sample payload.

Try JSON Minifier

Minify JSON context before sending it to a model — see bytes saved.