Language Data Format, v0.1

Tables a language model can read.

LDF turns JSON records into typed tables: one header, one line per record, child tables for nested arrays. Nothing is lost on the way in or out, and a frontier model reads it as well as JSON for 35 to 45 percent fewer tokens.

  • Lossless. Byte-exact round trip on ten of twelve benchmark datasets; the two sparse ones come back with keys reordered, nothing lost.
  • Typed. Integers, floats, strings, booleans, JSON cells and child tables, declared once in the header.
  • Measured. Four models, three sizes, ten formats. The misses are in the report, not hidden.
orders.ldf2 records, 1 child table
@records order_id:s,customer.id:i,customer.name:s,items:t,total:f,status:s,note:s?
ORD-000001,4654,Val Thompson,2,715.94,shipped,context compare
ORD-000002,50,Sol Ritchie,1,2757.03,cancelled,null
@records.items order_id:s,sku:s,qty:i,price:f
ORD-000001,E5,3,28.78
ORD-000001,C3,4,157.4
ORD-000002,A1,1,2757.03
the same data as JSON1.6x the tokens
[{"order_id":"ORD-000001","customer":{"id":4654,"name":"Val Thompson"},
  "items":[{"sku":"E5","qty":3,"price":28.78},{"sku":"C3","qty":4,"price":157.4}],
  "total":715.94,"status":"shipped","note":"context compare"},
 {"order_id":"ORD-000002","customer":{"id":50,"name":"Sol Ritchie"},
  "items":[{"sku":"A1","qty":1,"price":2757.03}],
  "total":2757.03,"status":"cancelled","note":null}]

The format

Seven rules. That is the whole spec.

A document is a sequence of tables. Each table is a header line and rows. Everything else follows from the data.

@records a:i,b:s

A header names the table and types each column: i integer, f float, s string, b boolean, j any JSON, t child table. ? marks a column that may be null or absent.

1,hello

A row is one record, cells separated by commas. Strings are bare unless they need quoting, then they are JSON strings.

, and null

An empty cell means the key is absent. null means it is present and null. JSON's distinction survives.

customer.name:s

Objects with a stable shape flatten into dotted columns. Irregular ones stay as a JSON cell.

@records.items

Arrays of objects become a child table joined on the parent's first column. The parent keeps a count.

~:j?

Keys present in fewer than half the rows travel in a small per-row object instead of a mostly empty column. Measured to matter for smaller models.

1.0 stays 1.0

Numbers keep their kind and shortest round-trip text. Integers above 2^53 do not get mangled.

Numbers

Tokens, as a share of compact JSON.

o200k_base tokens on the first 1 000 records of the benchmark datasets, from the report's own tables. CSV ties LDF where CSV works at all; CSV cannot hold nested data and drops the difference between missing and null.

datasetLDFTOONCSV
flat_users0.610.650.60
nested_orders0.641.08n/a
sparse_events0.801.220.61, lossy
wide_table0.430.440.43
empty_values0.361.27n/a
deep_nesting0.801.82n/a
131 / 150Claude Opus 5.5 at 200 records, zero wrong answers in LDF, the same score as every other format. The misses are an output cap on sums.
53 / 53GPT-6.1 Sol on LDF at 50 records, zero-shot: the prompt names the format and shows the data, nothing more.
17 / 18Claude Haiku 5.5 on 200 sparse events after the v0.1 sparse-key rule, JSON's score at 25 percent fewer tokens. Before the rule it was 13.

Below the frontier tier no format is reliably better than another, and the report says so. Read the methodology before quoting any number.

The middle man

Nobody has to adopt a format. Put it between the data and the model.

ldf-mcp is an MCP server. In proxy mode it wraps any stdio MCP server you already use, forwards every message, and re-encodes JSON tool results as LDF when that is shorter. The model keeps calling the same tools and receives cheaper data. In ClickHouse mode it is the server: read-only SQL over the HTTP interface, rows returned as LDF.

Claude Codeone line per server
claude mcp add clickhouse -- ldf-mcp clickhouse --url http://127.0.0.1:8123
claude mcp add my-data   -- ldf-mcp proxy -- <any stdio MCP server> [its args]
Primer once. The initialize result carries a short description of the format, so the model has read it before it sees any data.
Only what helps. Results under 1 KB, error results and non-text blocks pass through untouched.
A/B in the same session. A passthrough flag forwards JSON unchanged, for comparing answers and cost.

Status

A v0.1 prototype with its evidence attached.

One Rust workspace: the format, ten baseline formats implemented faithfully (TOON passes its official conformance suite), a benchmark harness, an evaluation harness and the MCP server. Every dependency pinned, no network calls outside the MCP server's own query.