ANo zip for Osaka
"ship": {"city": "Osaka"}
Row 3, ship cell
ORD-20003
TERse SETs.
It writes a set of records as one terse table, so a model reads the same data with fewer tokens.
pnpm add @stackdeck/terset8.7% fewer tokens than JSON. 19.8% fewer tokens than TOON.
1of 8
The 8 field names, written onceid customer status currency ship lines total note
Keys inside nested values stay JSON, so they still repeat. The tally counts them.
| Key | Written in JSON | In Terset | ||
|---|---|---|---|---|
| orders | 1 | 1 | ||
| id | 6 | 1 | ||
| customer | 6 | 1 | ||
| status | 6 | 1 | ||
| currency | 6 | 1 | ||
| ship | 5 | 1 | ||
| city | 4 | 4 | ||
| zip | 3 | 3 | ||
| lines | 6 | 1 | ||
| sku | 7 | 7 | ||
| qty | 7 | 7 | ||
| price | 7 | 7 | ||
| total | 6 | 1 | ||
| note | 1 | 1 | ||
| Total | 71 | 37 | ||
2of 8
orders: id customer status currency ship lines total note ORD-20001 Ana Silva paid USD {"city":"Lisbon","zip":"1100-148"} [{"sku":"A-100","qty":2,"price":9.99}] 19.98 ORD-20002 Ben Okafor shipped USD {"city":"Lagos","zip":"101233"} [{"sku":"B-220","qty":1,"price":24.5},{"sku":"D-400","qty":3,"price":7.25}] 46.25 ORD-20003 Chen Kim delivered USD {"city":"Osaka"} [{"sku":"E-555","qty":1,"price":39.9}] 39.9 Gift wrap ORD-20004 Dara Patel refunded USD null [] 0 ORD-20005 Eli Rossi paid USD [{"sku":"C-310","qty":2,"price":15}] 30 ORD-20006 Fatima Garcia shipped USD {"city":"Austin","zip":"78701"} [{"sku":"A-100","qty":1,"price":9.99},{"sku":"E-555","qty":1,"price":39.9}] 49.89
Sizes return when the JSON parses.Live sizes are in bytes. Token counts show for the samples.Sample tokens, o200k_base: Terset 325, JSON 356, TOON 405. Claude: Terset 500, JSON 553, TOON 530. Sample tokens, o200k_base: Terset 295, JSON 420, TOON 541. Claude: Terset 400, JSON 637, TOON 671. Sample tokens, o200k_base: Terset 139, JSON 99, TOON 118. Claude: Terset 225, JSON 153, TOON 148.
3of 8
orders: id customer status currency ship lines total note ORD-20001 Ana Silva paid USD {"city":"Lisbon","zip":"1100-148"} [{"sku":"A-100","qty":2,"price":9.99}] 19.98 ORD-20002 Ben Okafor shipped USD {"city":"Lagos","zip":"101233"} [{"sku":"B-220","qty":1,"price":24.5},{"sku":"D-400","qty":3,"price":7.25}] 46.25 ORD-20003 Chen Kim delivered USD {"city":"Osaka"} [{"sku":"E-555","qty":1,"price":39.9}] 39.9 Gift wrap ORD-20004 Dara Patel refunded USD null [] 0 ORD-20005 Eli Rossi paid USD [{"sku":"C-310","qty":2,"price":15}] 30 ORD-20006 Fatima Garcia shipped USD {"city":"Austin","zip":"78701"} [{"sku":"A-100","qty":1,"price":9.99},{"sku":"E-555","qty":1,"price":39.9}] 49.89
team: core users: id name role tags u1 Ada null u2 ops u3 "42" ["new"]
1orders:A root key on its own line. A list of records follows.2id customer ...The field names, written once, split by tabs.3ORD-20001A bare id header means each row starts with its id as plain text.4{"city":"Lisbon"}Nested values stay compact JSON inside the cell.5 empty cellAn empty cell means the field is absent. null stays null.6"42"Text that looks like a number, boolean or null gets JSON quotes.4of 8
"ship": {"city": "Osaka"}
Row 3, ship cell
ORD-20003
"ship": null, "lines": []
Row 4, ship cell
ORD-20004
"status": "paid", no "ship", "lines": […]
Row 5, empty ship cell
ORD-20005
"total": 39.9, "note": "Gift wrap"
Row 3, last cell
ORD-20003
5of 8
input{
"orders": [
{
"id": "ORD-20001",
"customer": "Ana Silva",
"status": "paid",
"currency": "USD",
"ship": {
"city": "Lisbon",
"zip": "1100-148"
},
"lines": [
{
"sku": "A-100",
"qty": 2,
"price": 9.99
}
],
"total": 19.98
},
{
"id": "ORD-20002",
"customer": "Ben Okafor",
"status": "shipped",
"currency": "USD",
"ship": {
"city": "Lagos",
"zip": "101233"
},
"lines": [
{
"sku": "B-220",
"qty": 1,
"price": 24.5
},
{
"sku": "D-400",
"qty": 3,
"price": 7.25
}
],
"total": 46.25
},
{
"id": "ORD-20003",
"customer": "Chen Kim",
"status": "delivered",
"currency": "USD",
"ship": {
"city": "Osaka"
},
"lines": [
{
"sku": "E-555",
"qty": 1,
"price": 39.9
}
],
"total": 39.9,
"note": "Gift wrap"
},
{
"id": "ORD-20004",
"customer": "Dara Patel",
"status": "refunded",
"currency": "USD",
"ship": null,
"lines": [],
"total": 0
},
{
"id": "ORD-20005",
"customer": "Eli Rossi",
"status": "paid",
"currency": "USD",
"lines": [
{
"sku": "C-310",
"qty": 2,
"price": 15
}
],
"total": 30
},
{
"id": "ORD-20006",
"customer": "Fatima Garcia",
"status": "shipped",
"currency": "USD",
"ship": {
"city": "Austin",
"zip": "78701"
},
"lines": [
{
"sku": "A-100",
"qty": 1,
"price": 9.99
},
{
"sku": "E-555",
"qty": 1,
"price": 39.9
}
],
"total": 49.89
}
]
}8 linesorders: id customer status currency ship lines total note ORD-20001 Ana Silva paid USD {"city":"Lisbon","zip":"1100-148"} [{"sku":"A-100","qty":2,"price":9.99}] 19.98 ORD-20002 Ben Okafor shipped USD {"city":"Lagos","zip":"101233"} [{"sku":"B-220","qty":1,"price":24.5},{"sku":"D-400","qty":3,"price":7.25}] 46.25 ORD-20003 Chen Kim delivered USD {"city":"Osaka"} [{"sku":"E-555","qty":1,"price":39.9}] 39.9 Gift wrap ORD-20004 Dara Patel refunded USD null [] 0 ORD-20005 Eli Rossi paid USD [{"sku":"C-310","qty":2,"price":15}] 30 ORD-20006 Fatima Garcia shipped USD {"city":"Austin","zip":"78701"} [{"sku":"A-100","qty":1,"price":9.99},{"sku":"E-555","qty":1,"price":39.9}] 49.89
outputWaiting for decode()Run the round trip below. The decoded JSON shows here.
Runs encode() and decode() on the six orders, in this page.Equal to the input: same values, same key order.The round trip did not match.
6of 8
Each case is scaled to its own largest count. Bar lengths compare real token counts within a case.
o200k_base: Terset, rules line included, is under TOON's best in 11 of 11 cases and under compact JSON in 9 of 11.
| Case | Terset | JSON compact | JSON pretty | YAML | TOON best | CSV | vs JSON compact | vs TOON |
|---|---|---|---|---|---|---|---|---|
| UI text, uneven rows | 504 | 695 | 1,190 | 802 | 846 | 473 lossy | −27.5% | −40.4% |
| UI text, uniform rows | 534 | 742 | 1,261 | 857 | 539 | 504 | −28.0% | −0.9% |
| Translation batch | 1,225 | 1,450 | 2,396 | 1,623 | 1,660 | 1,402 lossy | −15.5% | −26.2% |
| File list, short | 9,657 | 12,806 | 16,771 | 14,453 | 10,643 | n/a | −24.6% | −9.3% |
| File list, long | 16,483 | 19,627 | 23,595 | 22,129 | 17,476 | n/a | −16.0% | −5.7% |
| 200 users | 4,718 | 6,811 | 10,610 | 7,983 | 5,081 | 4,678 | −30.7% | −7.1% |
| Metrics, numbers and booleans | 2,569 | 4,797 | 7,557 | 6,115 | 2,654 | 2,531 | −46.4% | −3.2% |
| Deep nested config | 411 | 371 | 653 | 456 | 442 | n/a | +10.8% | −7.0% |
| Mixed-type array | 125 | 85 | 170 | 131 | 160 | n/a | +47.1% | −21.9% |
| Reviews, long text | 3,801 | 4,279 | 5,119 | 4,787 | 3,833 | 3,769 | −11.2% | −0.8% |
| Orders with line items | 3,968 | 4,585 | 7,749 | 5,673 | 4,419 | 4,952 lossy | −13.5% | −10.2% |
| Total | 43,995 | 56,248 | 77,071 | 65,009 | 47,753 | n/a | −21.8% | −7.9% |
CSV marked lossy did not read back to the same typed data. Terset counts include the rules line. Pretty JSON is in this table only, not in the chart.
Input cost at list price, US dollars per 1,000 requests. GPT 6.1 Sol at $2 per million input tokens, context up to 272K.
| Case | Terset | JSON compact | vs JSON compact |
|---|---|---|---|
| UI text, uneven rows | $1.01 | $1.39 | −$0.38 |
| UI text, uniform rows | $1.07 | $1.48 | −$0.41 |
| Translation batch | $2.45 | $2.90 | −$0.45 |
| File list, short | $19.31 | $25.61 | −$6.30 |
| File list, long | $32.97 | $39.25 | −$6.28 |
| 200 users | $9.44 | $13.62 | −$4.18 |
| Metrics, numbers and booleans | $5.14 | $9.59 | −$4.45 |
| Deep nested config | $0.82 | $0.74 | +$0.08 |
| Mixed-type array | $0.25 | $0.17 | +$0.08 |
| Reviews, long text | $7.60 | $8.56 | −$0.96 |
| Orders with line items | $7.94 | $9.17 | −$1.23 |
| Total | $87.99 | $112.50 | −$24.51 |
Tokens counted two ways: the o200k_base tokenizer and Claude's token count for Claude Opus 5.5. Others will differ. JSON means compact JSON, not pretty printed. The six orders above use o200k_base.
7of 8
Put RULES in the system prompt once. The data itself carries no legend.
import { encode, decode, RULES } from "@stackdeck/terset";
const system = RULES; // once, in the system prompt
const text = encode(data); // in the user messageTokens counted with one tokenizer, o200k_base. Others will differ. JSON means compact JSON, not pretty printed.
8of 8
Paste this into any coding agent before it builds a prompt.
For a coding agent that writes prompts. Paste it into its instructions.
Read https://terset.dev/agents.md before you write any prompt.
Install the @stackdeck/terset package from npm with pnpm add @stackdeck/terset, or the same package in the project's own package manager.
When a prompt carries a list of JSON records, encode it with Terset and put its RULES sentence in the system prompt once.
Keep JSON for config and tiny data, and ask for answers in JSON.
Config sample: 139 vs 99 tokens, +40.4%pnpm add @stackdeck/terset