Skip to main content

Benchmarks

These numbers come from the in-repo benches under bench/. Absolute times vary by hardware, Studio build, and load; use the ratios and relative ordering as the main takeaway.

Each operation is timed with BenchHelper: 50 warm-up calls, then 10 timed batches of 10,000 iterations. Reported Avg is mean microseconds per call across those batches.

Dynamo throughput

Source: benchresult/bench.txt
Harness: bench/Bench.luau

Values are average microseconds per call (μs). Lower is faster.

Scalars

TypeSerializeDeserializeRoundTrip
U80.060.020.09
I80.070.030.09
U160.070.020.09
F32~0.06~0.020.09
F64~0.06~0.020.09
Bool~0.06~0.02~0.09
Nil0.09

Strings, buffers, and datatypes

TypeRoundTrip (μs)
String (10 chars)0.25
String (100 chars)0.19
Buf (32b)0.17
Vector3— (see compare)
CFrame (quat)0.18
Color3~0.12
UDim20.13
EnumItem0.24

Collections

TypeRoundTrip (μs)
Array (1)0.20
Array (10)0.58
Array (100)4.12
Map (1)0.25
Map (10)1.29
Map (100)10.57

Primitive round trips stay near 0.09 μs. Cost grows mainly with collection size (per-element tags + payloads).

Versus VoidSentryUltimate and Sera

This comparison is a bit unfair since VoidSentryUltimate and Sera do not infer types at runtime, but Dynamo still managed to keep up well

Source: benchresult/compare.txt
Harness: bench/Compare.luau
Iterations: 10,000 per timed batch

Sera only serializes through schemas; the comparator wraps values in a single-field schema. VoidSentryUltimate uses typed nodes. Dynamo is schemaless (type tags on the wire).

RoundTrip wins in this run: VoidSentry 23, Dynamo 0, Sera 0 (of 23 cases).

Typical RoundTrip ratios (Dynamo ÷ VoidSentry)

CaseApprox. ratio
Scalars / Bool~1.3×
String8 / Buffer / Color3 / CFrame quat~1.1–1.2×
Vector3~2.4×
Array (10)~1.9×
Map (10)~1.7×
UDim2~1.4× (Dynamo smaller on wire: 9b vs 16b)

Versus Sera

On shared primitives and buffers, Dynamo is generally faster than Sera on RoundTrip (often ~1.5–2×). Sera’s Buffer16 RoundTrip was an outlier (~0.72 μs) in this run.

How to read this

  • Schemaless tags cost ~1 byte and a small infer/dispatch cost versus schema-fixed VoidSentry nodes.
  • Collection gaps are dominated by per-element tags (size and time).
  • Prefer Dynamo when you want dynamic values without maintaining schemas; prefer a schema library when every field type is known and bandwidth/CPU are tighter.

Versus other dynamic serializers

Source: benchresult/comparedynamic.txt
Harness: bench/CompareDynamic.luau
Iterations: 10,000 per timed batch

Compares Dynamo to BlazeSentry dynamic, BufferEncoder, MessagePack, and HttpService:JSONEncode / JSONDecode. Each library only runs on types it actually supports (Blaze has no nil / buffer / UDim2; MessagePack/JSON skip Roblox datatypes; BufferEncoder wraps non-tables and skips bare nil).

RoundTrip wins in this run: Dynamo 18, MessagePack 2, Blaze 0, BufferEncoder 0, JSON 0 (of 20).

MessagePack’s two wins: I8 (essentially tied at ~0.10 μs) and Array (10).

RoundTrip (μs)

CaseDynamoBlazeBEMsgPackJSON
U80.090.300.520.100.44
I80.100.290.520.100.43
U160.090.300.520.140.44
I160.090.290.520.140.43
U320.090.290.520.180.44
I320.100.300.520.180.46
F320.090.290.510.280.43
F640.100.300.510.290.44
Bool0.090.300.510.100.37
Nil0.080.100.38
String (10)0.120.330.550.140.44
Array (10)0.901.270.950.751.18
Map (10)1.572.622.041.801.66
Buffer (8b)0.160.650.17
Buffer (32b)0.170.630.20
Vector30.090.310.54
Vector20.100.320.55
Color30.110.340.56
CFrame0.170.430.72
UDim20.130.57

Wire size (bytes)

CaseDynamoBlazeBEMsgPackJSON
U822512
Array (10)2222221122
Map (10)6364634273
CFrame294923
UDim2920

Takeaways

  • Against other schemaless / dynamic encoders, Dynamo leads RoundTrip on almost every shared case (~3× Blaze on scalars, ~5× BufferEncoder, ~4× JSON).
  • MessagePack stays competitive on small integers and wins dense numeric arrays (no per-element type tags). Dynamo stays ahead on maps and Roblox datatypes MessagePack cannot encode.
  • BufferEncoder pays for a table root + richer type system; size and time trail Dynamo on these fixtures.
  • Blaze dynamic matches Dynamo’s wire size on many scalars but is ~3× slower RoundTrip here.
  • Prefer Dynamo for mixed Roblox + Luau payloads without schemas; prefer MessagePack when the payload is MsgPack-only Luau data and array density matters.

Re-run locally:

require(path.to.Bench)(true)
require(path.to.Compare)(true)
require(path.to.CompareDynamic)(true)