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.08
I80.050.020.08
U160.060.020.08
F320.050.020.08
F640.060.020.08
Bool0.060.020.08
Nil0.050.020.07

Strings, buffers, and datatypes​

TypeRoundTrip (μs)
String (10 chars)0.12
String (100 chars)0.16
Buf (32b)0.15
Vector30.08
CFrame (quat)0.16
Color30.10
UDim20.12
EnumItem0.21

Collections​

TypeRoundTrip (μs)
Array (1)0.18
Array (10)0.49
Array (100)3.24
Map (1)0.22
Map (10)1.03
Map (100)8.30

Primitive round trips sit around 0.08 μ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 / Vector3~1.14×
String8 / Buffer / Color3 / CFrame quat~1.07–1.20×
Array (10)~1.6×
Map (10)~1.4×
UDim2~1.3× (Dynamo smaller on wire: 9b vs 16b)

Versus Sera​

On shared primitives and buffers, Dynamo is about 2× faster than Sera on RoundTrip (scalars ~0.08 μs vs ~0.16 μs). Sera stays slower on CFrame quat (~0.28 μs vs Dynamo 0.16 μs).

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 20, Blaze 0, BufferEncoder 0, MessagePack 0, JSON 0 (of 20).

RoundTrip (μs)​

CaseDynamoBlazeBEMsgPackJSON
U80.080.300.520.110.41
I80.080.300.520.100.42
U160.080.300.520.140.43
I160.080.300.520.140.42
U320.080.310.520.190.43
I320.090.300.530.190.44
F320.080.300.510.290.43
F640.120.300.520.300.43
Bool0.080.310.520.100.36
Nil0.08——0.110.37
String (10)0.110.340.560.150.43
Array (10)0.501.240.950.761.16
Map (10)1.322.662.031.931.61
Buffer (8b)0.14—0.590.17—
Buffer (32b)0.15—0.600.19—
Vector30.080.310.53——
Vector20.090.330.55——
Color30.110.330.56——
CFrame0.160.450.72——
UDim20.12—0.57——

Wire size (bytes)​

CaseDynamoBlazeBEMsgPackJSON
U822512
Array (10)2222221122
Map (10)6364634273
CFrame294923——
UDim29—20——

Takeaways​

  • Against other schemaless / dynamic encoders, Dynamo leads RoundTrip on every shared case in this run (~3.7× Blaze on scalars, ~6× BufferEncoder, ~5× JSON).
  • MessagePack stays closest on small integers and dense numeric arrays (no per-element type tags). Dynamo still wins those cases here and leads 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–4× 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)