Benchmarks
Measured on AMD EPYC 7763 64-Core Processor, Node 24.21.0, when this site was built (2026-10-17). The fixtures are in fixtures/index.mjs. Run pnpm compare to measure on your machine.
Size
| Payload | JSON | TOON | Flat Notation | vs JSON | JSON gzip | Flat gzip |
|---|---|---|---|---|---|---|
| users (100 rows) | 16,691 B | 18,589 B | 9,151 B | −45% | 1,496 B | 1,401 B |
| users (1000 rows) | 169,545 B | 188,544 B | 93,606 B | −45% | 12,890 B | 12,568 B |
| profile (single object) | 146 B | 133 B | 151 B | +3% | 135 B | 128 B |
| events (mixed shapes) | 3,606 B | 3,785 B | 3,179 B | −12% | 383 B | 367 B |
| contacts (optional keys, 1000) | 101,947 B | 110,753 B | 59,707 B | −41% | 11,288 B | 10,701 B |
| activity feed (500 events) | 162,440 B | 184,935 B | 169,092 B | +4% | 12,447 B | 12,101 B |
Speed
The median of 7 runs of 50 iterations each.
| Payload | JSON.parse | TOON decode | FlatType decode | FlatType encode |
|---|---|---|---|---|
| users (100 rows) | 0.096 ms | 1.864 ms | 0.324 ms | 0.316 ms |
| users (1000 rows) | 1.102 ms | 38.454 ms | 1.933 ms | 1.949 ms |
| profile (single object) | 0.001 ms | 0.013 ms | 0.006 ms | 0.005 ms |
| events (mixed shapes) | 0.026 ms | 0.370 ms | 0.166 ms | 0.162 ms |
| contacts (optional keys, 1000) | 0.606 ms | 7.949 ms | 1.464 ms | 1.990 ms |
| activity feed (500 events) | 0.760 ms | 13.249 ms | 4.008 ms | 2.783 ms |
What these numbers mean
- The savings come from lists of objects. Keys are written once per table instead of once per row, and nested fields go into the header. A single small object is about the size of its JSON.
- Lists whose objects have different keys (the contacts, the activity feed and the mixed events) use Flat Notation 1.1: tables with optional fields such as
phone?, and[+]items for what can't be a table. Before v1.14 they were written with an index on every line, larger than JSON and twice its size after gzip. - Gzip removes most of JSON's repetition, so over a compressed connection the difference is small. The big wins are where text isn't compressed: LLM prompts and tool results (billed per token), logs, caches and local storage.
JSON.parseis native code and stays faster. FlatType's decoder is plain TypeScript and runs in time linear in the input size, which the hardening tests check on every push.- TOON is the Token-Oriented Object Notation reference implementation, measured with the same fixtures. It doesn't flatten nested objects into table headers, so on the list payloads here it comes out larger than JSON.