Compressing Chat History with TOON for Cheaper, Longer Conversations
Conversation history grows every turn and you pay for it every request. Learn how TOON-encoding message arrays plus prompt caching keeps long chats inside budget.
TOON-encode your messages array. Conversation history is a uniform array of role/content objects — the exact shape where TOON saves the most tokens. Official benchmarks show up to 58.8% fewer tokens on uniform arrays versus JSON. Pair that with prompt caching and the two discounts multiply: fewer tokens in the cache block, cheaper to write, cheaper to re-read on every subsequent turn.
Why Conversation History Is an Expensive Line Item
Every LLM API call includes the full conversation history so the model can maintain context. That means you pay for every prior message on every single turn. A 20-turn conversation does not cost 20 units of tokens — it costs roughly 1 + 2 + 3 + … + 20 = 210 units of message-sized chunks. The history grows quadratically relative to cost.
Most developers think about this as a context-window problem — "will the history fit?" — but it is equally a cost problem. Even when the history comfortably fits inside a 128K or 200K context window, you are re-paying for every older message on every new request. For a production chatbot handling thousands of sessions, this compounds quickly. The guide to building cost-efficient chatbots covers the full cost model.
The structure of a messages array is also almost perfectly suited for TOON compression. Every message is an object with the same two or three fields: role, content, and sometimes a name or timestamp. That uniform schema is exactly what TOON's header-once table block was designed to exploit.
JSON vs TOON for a Messages Array: A Direct Comparison
Here is a six-turn conversation encoded both ways. The JSON version repeats the field names on every object. The TOON version declares them once in the header.
// JSON messages array — field names repeat on every object
[
{"role": "system", "content": "You are a helpful assistant."},
{"role": "user", "content": "What is the capital of France?"},
{"role": "assistant", "content": "The capital of France is Paris."},
{"role": "user", "content": "What is its population?"},
{"role": "assistant", "content": "Paris has roughly 2.1 million residents in the city proper."},
{"role": "user", "content": "Thanks, that is helpful."}
]
// TOON messages table — fields declared once; rows are values only
messages[6]{role,content}:
system, You are a helpful assistant.
user, What is the capital of France?
assistant, The capital of France is Paris.
user, What is its population?
assistant, Paris has roughly 2.1 million residents in the city proper.
user, Thanks, that is helpful.The JSON version encodes "role" and "content" as quoted key strings six times each, plus twelve pairs of braces and twelve colons. In the TOON version those field names appear exactly once. As the conversation grows from 6 turns to 60, the JSON overhead scales linearly while the TOON header cost stays constant.
According to the official toonformat.dev benchmarks — which ran 5,016 LLM calls across 209 questions, six formats, and four models — flat uniform arrays see 58.8% fewer tokens in TOON versus JSON (67,778 vs 164,452 tokens). A messages array is exactly a flat uniform array. Overall across all data shapes, TOON achieves 39.9% fewer tokens while maintaining 76.4% retrieval accuracy, slightly above JSON's 75.0%.
How Prompt Caching Stacks with TOON History Compression
Token compression and price-per-token caching are independent discounts that multiply. TOON reduces how many tokens you send; prompt caching reduces what you pay per token for the stable prefix you send repeatedly.
Anthropic: Cache reads cost 10% of the input rate — a 90% discount. Cache writes cost 1.25x or 2x the base input rate depending on TTL (5-minute or 1-hour). The discounts are documented on the Anthropic prompt caching page.
OpenAI: Caching is automatic once a stable prefix exceeds 1,024 tokens. The cached portion is billed at roughly 50% of the input rate. This is ideal for a TOON-encoded history block: you encode the older turns into a compact, stable TOON prefix, and the cache kicks in automatically once that prefix exceeds the threshold. Details are in the prompt caching reference.
The key insight from the benchmarks: caching discounts the price per token; TOON cuts the number of tokens. A smaller cached block is cheaper to write to cache AND cheaper to re-read on every subsequent turn. See the full API cost optimization guide for worked examples with real pricing figures.
Cost and Token Effect: Three Approaches Compared
The table below compares the relative effect of each strategy. Exact totals depend on message length and provider pricing; the directional relationships are grounded in the benchmark and caching data cited above.
| Approach | Token count effect | Price-per-token effect | Implementation effort | Notes |
|---|---|---|---|---|
| Full JSON history | Baseline | Standard input rate | None — default behavior | Cost scales linearly with turns; fine for short sessions |
| TOON-encoded history | Up to ~59% fewer (uniform array benchmark) | Standard input rate | Convert messages array before each API call | Keep 2–3 most recent turns verbatim; compress older turns |
| TOON history + prompt caching | Up to ~59% fewer tokens | 10% of input rate (Anthropic) or ~50% (OpenAI) on cached reads | Encode history as TOON; mark prefix as cacheable or rely on auto-cache | Both savings multiply; largest gain for long-running sessions |
For a head-to-head on how TOON compares to raw JSON across different data shapes, see the JSON vs TOON deep-dive.
The Practical Pattern: Compress Old History, Keep Recent Turns Verbatim
Not all turns should be treated the same. The most recent two or three exchanges carry the highest contextual weight — the model needs full fidelity on the immediate back-and-forth. Compressing them into a TOON row truncates nothing, but it does add a tiny parsing step that is worth avoiding for turns the model will attend to most closely.
The recommended pattern is a split approach:
- Older history (turn N and earlier): encode as a TOON table block. This section is stable and does not change between turns — making it a perfect prompt-caching candidate. Mark it as the cached prefix.
- Recent context (last 2–3 turns): keep as standard JSON or plain text. This is the active, changing portion of the conversation.
- New user message: append after the cached prefix in the normal format.
This structure also aligns well with how context window management libraries like LangChain handle message windowing. The older, compressed portion can be summarized further if needed, but TOON compression alone — at up to 58.8% reduction — often buys enough runway before summarization is required.
The arXiv study on TOON (arXiv 2603.03306) confirmed that TOON's efficiency advantage is strongest on large, repetitive payloads — exactly what a long conversation history is. For short conversations of fewer than roughly ten turns, the format-instruction overhead can narrow the gains, so measure on your actual data before committing the pattern to production.
Which Models Handle TOON-Encoded History Best?
The official benchmarks tested four models. Gemini 3 Flash achieved 96.7% overall accuracy with TOON, GPT-5 Nano reached 90.9%, while Claude Haiku scored 59.8% and Grok 4.1 scored 58.4%. For a messages table with only two fields — role and content — every model should perform at or near the top end of its range, since this is one of the simplest possible TOON structures.
Field retrieval accuracy across all models sits at 99.6% — essentially perfect. The model will reliably read each role and content value from the table. The lower accuracy figures appear on aggregation and filtering tasks, which are not relevant to reading conversation history.
Include a single sentence in your system prompt on first use: something like "Conversation history is provided in TOON tabular format: each row is a turn, columns are role and content." After that, no further format instructions are needed within the session, keeping the prompt-tax overhead to a minimum.
For a broader look at how TOON fits into a cost-efficient LLM architecture, see what is TOON? and the companion post on using TOON for log analysis, which covers the same header-once table approach applied to application log data.
Frequently Asked Questions
How do I reduce the token cost of chatbot conversation history?
TOON-encode your messages array. A conversation history is a uniform array of role/content objects — exactly the shape where TOON saves the most. Official toonformat.dev benchmarks record up to 58.8% fewer tokens on uniform arrays versus JSON. Combine that with prompt caching for a second multiplicative discount on the stable history prefix.
How much can TOON reduce conversation history tokens?
A messages array is a uniform array of objects sharing the same schema — role and content. Official toonformat.dev benchmarks show 58.8% fewer tokens on flat uniform arrays versus JSON. Overall across mixed data, TOON averages 39.9% fewer tokens while achieving 76.4% retrieval accuracy, higher than JSON's 75.0%.
What is prompt caching and how does it stack with TOON?
Prompt caching discounts the price per cached token: Anthropic charges 10% of the input rate for cache reads (90% off); OpenAI auto-caches stable prefixes over 1,024 tokens at roughly 50% of input cost. TOON cuts the number of tokens. Both savings are multiplicative — a smaller TOON-encoded history block is cheaper to write to cache and cheaper to re-read.
Should I compress the most recent messages in the conversation?
No. Keep the most recent two or three turns verbatim so the model has full fidelity on the immediate context. Apply TOON compression to older history — the turns that are stable and unlikely to change — since that portion is where prompt caching also applies most reliably.
Does the LLM still understand the conversation when history is TOON-encoded?
Yes. TOON's field retrieval accuracy is 99.6% in official benchmarks, and a messages table with two fields — role and content — is among the simplest possible TOON structures. The model reads the role column and content column from the table header and extracts each turn reliably. Include a brief format note in your system prompt on first use.
Recommended Reading
Halving Costs Twice: The OpenAI Batch API Plus TOON
The Batch API takes 50% off input and output tokens; TOON removes 40-60% of them first. Here's how to combine async batching and token-efficient formatting for bulk LLM jobs.
Stacking TOON with Prompt Caching to Cut LLM Costs Further
Prompt caching cuts the price per token up to 90%; TOON cuts the number of tokens up to 60%. Learn how to combine both levers for compounding savings on Claude and GPT.
Edge AI on a Token Budget: Running Local LLMs with TOON
Small local models like Llama and Phi have tiny context windows. Learn how TOON's compact tables stretch limited context for on-device and edge AI.