7 min read

TOON Keyed Tables: Encoding Maps of Objects in Fewer Tokens

TOON keyed tables collapse objects keyed by ID or name, like feature flags or user maps, into one table. Syntax, rules and the 54.6% savings vs JSON.

By json2toon.co

TOON keyed tables encode an object of uniform objects, such as feature flags by name or users by ID, as one table. Field names appear once in the header and each row starts with its own key. Added in spec 4.0, the form cut tokens by 54.6% vs JSON on the official feature-flags benchmark.

What problem do keyed tables solve?

TOON has always turned uniform arrays into compact tables. But plenty of real data is a map: config keyed by environment, feature flags by name, records by ID. Before v4, these were written as nested blocks with every field name repeated, much like YAML. Spec 4.0 (July 22, 2026) added the keyed tabular form for this shape (RFC #57 in the spec changelog). For the other v4 changes, see what's new in TOON v4.

What does a keyed table look like?

Four feature flags in JSON:

{
  "flags": {
    "darkMode": {
      "enabled": true,
      "rollout": 50,
      "owner": "web"
    },
    "newCheckout": {
      "enabled": false,
      "rollout": 0,
      "owner": "payments"
    },
    "betaSearch": {
      "enabled": true,
      "rollout": 10,
      "owner": "search"
    },
    "aiSummaries": {
      "enabled": true,
      "rollout": 25,
      "owner": "ml"
    }
  }
}

And the same data as encoded by @toon-format/toon 4.1.1:

flags[4:]{enabled,rollout,owner}:
  darkMode: true,50,web
  newCheckout: false,0,payments
  betaSearch: true,10,search
  aiSummaries: true,25,ml

How to read it: [4:] declares four entries, and the colon after the count marks the keyed form (a plain array header is [4]). {enabled,rollout,owner} lists the shared fields. Each row is entrykey: cells. With the o200k_base tokenizer we counted 126 tokens for the pretty JSON, 72 for minified JSON and 54 for TOON. The decoder rebuilds the original object exactly, with keys in row order.

How much do keyed tables save?

The official benchmark added a "Feature flags keyed by name" dataset (40 records) to measure this form (token-efficiency results):

FormatTokensTOON difference
TOON (keyed table)10,503n/a
JSON compact15,635−32.8%
YAML17,905−41.3%
JSON23,141−54.6%
XML28,655−63.3%

Accuracy held up as well. On that dataset TOON answered 97.1% of questions correctly, compared with 95.6% for JSON and 94.1% for minified JSON (retrieval-accuracy results). The dataset is small (68 answers per format), so read that as "no loss" rather than proof of a gain. This is one of the shapes where TOON beats even minified JSON. Our TOON vs minified JSON comparison shows the shapes where it does not.

When does TOON use the keyed form?

Section 9.5 of the TOON spec defines detection. An object becomes a keyed table only if:

  • it has at least two entries;
  • every value is a non-empty object;
  • all values have the same set of keys (order may vary);
  • every column holds primitives, or uniform nested objects (encoded as nested field groups).

When these conditions hold, encoders must use the form (spec 4.1 removed encoder discretion). When they fail, the object stays nested. All of these stay nested in 4.1.1:

flags:
  darkMode:
    enabled: true
    rollout: 50
  newCheckout:
    enabled: false

Above, newCheckout has no rollout, so the key sets differ. A single-entry map also stays nested, and so does a map whose values contain an array or an empty object. Maps of primitives (free: 10, pro: 100) are already plain key-value lines and don't need a table.

Can keyed tables hold nested objects?

Yes. If every entry has a sub-object with the same keys, the header uses a nested field group, the other v4 addition:

stores[2:]{manager,address{city,zip},open}:
  berlin: Lena,Berlin,"10115",true
  paris: Hugo,Paris,"75001",false

Note the quoted "10115". The source data held the zip code as a string, and the encoder quotes it so it does not decode as a number.

What about root objects, odd keys and other delimiters?

If the whole document is a map of uniform objects, the key is dropped and the header starts with the bracket:

[3:]{name,plan,seats}:
  u_1001: Ada Lovelace,pro,5
  u_1002: Grace Hopper,team,12
  u_1003: Alan Turing,free,1

Entry keys follow normal TOON key rules, so keys with slashes or spaces, or keys starting with a digit, are quoted:

prices[3:]{bid,ask}:
  "EUR/USD": 1.08,1.09
  "user 42": 2,3
  "2fa": 1,1

Delimiters work as they do for arrays. With the pipe option, the header becomes flags[2:|]{enabled|note}:, and commas inside values no longer need quotes:

flags[2:|]{enabled|note}:
  darkMode: true|a,b
  beta: false|c

Our delimiter guide covers when tab or pipe saves more.

Where can keyed tables not appear?

Array elements are anonymous, so they never use the keyed form, and there is no - [N:]{...}: list item. A keyed table can be a field of a list-item object, though. In that case its header sits on the hyphen line:

tenants[2]:
  - flags[2:]{on,pct}:
      search: true,10
      export: false,0
    name: acme
  - name: globex
    plan: free

How strict is decoding?

In strict mode (the default) the decoder checks the declared count and the width of every row. A header that says [3:] with only two rows fails with Expected 3 keyed entries, but got 2. A row with a missing cell fails with Expected 2 keyed entry cells, but got 1. That makes truncated or corrupted context easy to detect.

The other side: decoders older than v4 cannot read keyed tables. Strict v3 decoders reject them, and non-strict ones silently produce wrong data. If any service decodes your TOON, follow the order in our TOON v4 migration guide and upgrade decoders first.

To see whether your own maps qualify, paste them into the JSON to TOON converter, or check the syntax reference in the TOON docs.

Frequently Asked Questions

What is a keyed table in TOON?

A keyed table is the TOON v4 encoding for an object whose values are all objects of the same shape, such as feature flags keyed by name. The header lists the shared fields once, for example flags[3:]{enabled,rollout}:, and each row starts with its own key followed by a colon and the values.

When does TOON use the keyed tabular form?

When the object has at least two entries, every value is a non-empty object, all values have the same set of keys, and every column holds primitives or uniform nested objects. Encoders must then use it. Single-entry maps, maps with differing keys and maps whose values contain arrays stay in nested form.

How much do keyed tables save compared with JSON?

On the official benchmark's feature-flags dataset, TOON used 54.6% fewer tokens than pretty JSON, 32.8% fewer than minified JSON and 41.3% fewer than YAML. It also scored 97.1% accuracy on that dataset, the highest of the formats tested.

Can older TOON decoders read keyed tables?

No. Keyed tables arrived in spec 4.0. Strict v3 decoders reject the header, and non-strict ones mis-decode it silently. Upgrade every decoder to @toon-format/toon 4.x, or another v4 implementation, before you upgrade the encoders that produce keyed tables.

Recommended Reading

TOONTOON v4Keyed TablesJSONToken EfficiencyTutorial