Your LLM is billing you for whitespace
Figure 1Time to the full answer on ten models, with the same answer written normally and minified
Reading the inputThinkingWriting the answer The difference
On this page
Ask a model for structured output and many will pretty-print the JSON, with a newline and indentation for every field. You pay for those tokens, and you wait while they are generated. One sentence in the prompt turns it off. We tested ten models. On seven it saves time and money. On three it does nothing, because they already emit single-line JSON.
The three parts of a call
A call has three phases: reading the input, optional thinking, and writing the answer.
Figure 2The three phases of an AI call, and what minified JSON changes in each
Reading the input: 3.8 s, 9,593 tokens Thinking: 0.0 s, 0 tokens Writing the answer: 26.7 s, 2,296 tokens
Reading the input: 6.6 s, 9,596 tokens Thinking: 32.8 s, 1,944 tokens Writing the answer: 8.6 s, 1,177 tokens
Reading the inputTime to first token, including network and queueing. Unchanged by minified JSON.
ThinkingReasoning models only. Should not change, but did on some models.
Writing the answerThe JSON itself. The only part minified JSON shortens.
Minified JSON only touches the last phase. The input does not change, so prefill time and input cost stay the same.
One sentence in the prompt
Pretty-printed, our meal schema comes back like this:
{
"meal_name": "Bangers and mash with peas and onion gravy",
"confidence": "high",
"items": [...],
"notes": "The big unknown is the butter and milk in the mash.",
"questions": [
{
"question": "How rich was the mashed potato?",
"choices": [
"Standard (a dash of milk, knob of butter)",
"Rich (heavy cream or lots of butter)",
"Light (mostly just milk or potato water)"
],
"kcal_at_stake": 95,
"impacts": [
{
"choice": "Rich (heavy cream or lots of butter)",
"items": [...]
},
...
Minified, the same content is one line:
{"meal_name":"Bangers and mash with peas and onion gravy","confidence":"high","items":[...],"notes":"The big unknown is the butter and milk in the mash.","questions":[{"question":"How rich was the mashed potato?","choices":["Standard (a dash of milk, knob of butter)","Rich (heavy cream or lots of butter)","Light (mostly just milk or potato water)"],"kcal_at_stake":95,"impacts":[{"choice":"Rich (heavy cream or lots of butter)","items":[...]},...
The instruction we appended to the system prompt:
Write the JSON minified: one line, no spaces or line breaks outside string values.
Which models indent
To measure the whitespace, we took each model's normal answers and counted them as written and minified, with the model's own tokenizer.
Figure 3Tokens per call on each model, and the share of the answer that is whitespace
Input tokensThinking tokensAnswer tokens Spaces and line breaks
Five models indent every answer, and whitespace is 27 to 34% of their output tokens. GLM and Qwen indent some answers, or only partly. Claude Opus, Kimi and Grok wrote single-line JSON.
Whether a model indents depends on the request, not only on the model. On a tiny prompt with a small strict schema, Gemini 3.8 Flash, GPT-6.1 and DeepSeek wrote one line without being asked. On our real request, with a long system prompt and a large schema, Gemini 3.8 Flash, Gemini 4 Argon and Mistral indented with strict mode on or off. Qwen only indented with strict mode off. So look at what your model writes for your own request.
The output is a small share of the tokens in a call, but most of the latency. The model reads the whole input in one parallel pass, but writes the output one token at a time.
Where it saves time
Figure 1 shows the latency per model. The gain is largest on models that start writing straight away. Gemini 4 Argon goes from 30.5 to 21.4 seconds, 30% faster. Mistral Large is 25% faster, Gemini 3.8 Flash and GPT-6.1 21 to 22%.
On reasoning models the gain is smaller. DeepSeek and Qwen think for about 20 and 45 seconds before they write, so the same cut in output is 7% of the total.
Where it saves money
Figure 4Cost per 1,000 calls on each model, with and without minified JSON
The inputThinkingThe answer The difference
Output tokens cost at least three times as much as input tokens on every model here, and minified JSON only shrinks the output. What that does to the bill depends on the output's share. Gemini 4 Argon and GPT-6.1 are 25 to 28% cheaper. Gemini 3.8 Flash and Mistral are 13% cheaper, because their input costs as much as the answer or more. On the reasoning models, thinking is billed as output and does not shrink, so they save 5 to 9%.
Where it does nothing
Claude Opus, Kimi and Grok already wrote minified JSON on our request. Their answers are byte-identical to the minified version, so there is nothing to save.
Asking anyway can only cost you. In our runs, Grok thought about twice as long with the instruction. With four runs that may be noise, but there is no upside.
How we measured
We sent the same meal photo, prompt and JSON schema to ten models from nine providers, four runs with the instruction and four without. The models followed it in 39 of 40 answers. Mistral Large ran with thinking off, because with it on it never finished an answer.
To compare like with like, we counted each model's normal answers both as written and minified, with its own tokenizer. The time and cost saved follow from the tokens removed, at the model's own decode speed and output price.
What to test on your own implementations
- Check your model's raw output. If it pretty-prints, ask for minified JSON.
- It pays most on models that start writing immediately. With long reasoning, the output is a small share of the latency.
- If the model already emits one line, leave the instruction out.
- Measure with token counts of the same answer, not a handful of timed runs.
Snapkin now asks for minified JSON on every meal analysis, and on every correction you make to one.