Skip to content

Benchmark Fixtures

The benchmark harness and Playground use the same named payloads. This page documents what each fixture contains so you can interpret size and throughput numbers correctly.

Fixture catalog

NameRecordsShapePurpose
single-small1Nested 6-field objectBaseline single-record comparison
batch-homogeneous-256256Identical 6-field schemaShape interning win
batch-mixed-2562564 variant shapes (rotating)Realistic heterogeneous batch
patch-session2 ticksSame object, 1 field changeStateful patch savings

single-small

One user-like object with nested profile:

json
{
"id": 1234,
"userId": 987654,
"name": "alice",
"active": true,
"score": 98.5,
"tags": ["edge", "premium", "ap-northeast-1"],
"profile": {
"country": "JP",
"locale": "ja-JP",
"timeZone": "Asia/Tokyo"
}
}

What it tests: Single-record encode/decode throughput. Twilic ≈ MessagePack size (no batch interning yet).

Compared formats: Twilic, MessagePack, CBOR, BSON, JSON.

batch-homogeneous-256

256 records with identical field layout:

json
{
"id": 1,
"userId": 100001,
"active": true,
"tier": "standard",
"country": "JP",
"usage": { "requests": 5001, "errors": 1 }
}

Fields vary by index (tier alternates "gold" / "standard", country mostly "JP"), but shape is fixed.

What it tests: Row batch shape interning and string dedup. Twilic typically benefits strongly versus MessagePack because repeated field names and repeated strings are amortized.

batch-mixed-256

256 records rotating through 4 different object shapes:

VariantDistinct fields
Type Aid, tenant, active, metrics, tags
Type Bid, name, score, flags
Type Cid, status, count, metadata
Type Did, value, timestamp, source

What it tests: Batch compression when schema is not uniform. Twilic still wins but margin is smaller than homogeneous batch.

patch-session

Two consecutive values representing a stateful stream tick:

Tick 1 (full frame):

json
{
"id": 9001,
"status": "active",
"score": 99.1,
"profile": { "country": "JP", "locale": "ja-JP", "timeZone": "Asia/Tokyo" }
}

Tick 2 (patch — only score changes):

json
{
"id": 9001,
"status": "active",
"score": 99.2,
"profile": { "country": "JP", "locale": "ja-JP", "timeZone": "Asia/Tokyo" }
}

What it tests: encodePatch() vs full encode() on tick 2. Patch is typically 85–92% smaller than re-encoding the full object.

Twilic encode variants (benchmark --mode max)

The extended benchmark suite also measures internal encode paths:

VariantAPIDescription
defaultencode()Standard Dynamic profile
directencodeDirect()Bypass JS value tree
compactencodeCompact()Compact JSON intermediate
raw jsonencodeTransportJson()Transport-JSON string input
compact rawencodeCompactJson()Pre-serialized compact JSON

See Performance — JS hot paths.

Playground alignment

The Playground Encoded sizes view uses these same fixture names. You can also paste custom JSON to compare ad-hoc payloads.

The Schema-first view uses UserRecordV1 from schema-example.json at ×1, ×3, and ×256 record counts. v3 reports should compare BOUND_STREAM and SCHEMA_BATCH against Protobuf, Avro, FlatBuffers, and Arrow IPC with schema sharing and framing assumptions disclosed.

Examples repo fixtures

Shared fixtures in examples/shared/fixtures.ts power the runnable examples:

ExampleFixture helperProfile
API responseUser list pageBatch
TelemetryEvent arraycol_batch / SCHEMA_BATCH
Cache payloadSession blobDynamic
LogsLog eventsBatch / micro-batch
WebSocketDashboard metricsStateful

Running benchmarks

bash
git clone https://github.com/twilic/benchmark.git
cd benchmark
pnpm install
pnpm bench # standard suite
pnpm bench -- --mode max # all encode variants
pnpm bench -- --twilic-vs-msgpack-only # hide JSON rows
pnpm bench -- --backend wasm # WASM backend

Released under the CC-BY-4.0 License.