Skip to content

Performance

Synapse has been extensively benchmarked at every layer — SwitchBoard throughput (JMH on JVM), interceptor pipeline scaling, provider dedup, coordinator lifecycle, and Node composition cost (on-device Android benchmarks). The results below are from v1.0.9.

OperationSynapseBare FlowOverhead
State broadcast + collect0.759 µs0.553 µs1.37x
Impulse trigger (end-to-end)0.863 µs
Request/response (via Provider)4.458 µs

The SwitchBoard adds ~200 ns over raw SharedFlow for state broadcast — the cost of type-based routing and the interceptor pipeline check. Impulse delivery and request/response are similarly in the single-digit microsecond range.

CollectorsThroughput (ops/µs)Scaling
10.792baseline
50.151linear
100.075linear
500.015linear

Fan-out scales linearly with collector count. No degradation or contention effects.

PipelineCost per emission
0 interceptorsbaseline
1 read-only+20 ns
1 transform+20 ns
5 mixed+100 ns
10 mixed+200 ns

Each interceptor adds ~20 ns. Even a pipeline of 10 interceptors adds only 200 ns total — negligible relative to any real business logic.

Compose Node composition (on-device, Pixel 9 Pro Fold)

Section titled “Compose Node composition (on-device, Pixel 9 Pro Fold)”

Base cost of composing a single Node (CreateContext + Node + state init): ~380 µs.

Sibling Node scaling (flat, in one CreateContext):

Sibling countMedianPer-Node cost
5490 µsbaseline
10610 µs~24 µs
20830 µs~22 µs
501.48 ms~22 µs
1002.48 ms~21 µs
2004.54 ms~21 µs

Nested Node scaling (each level wraps the next):

DepthMedianPer-level cost
1400 µsbaseline
5500 µs~25 µs
10540 µs~16 µs
20710 µs~16 µs
501.27 ms~18 µs
1002.57 ms~22 µs

Scaling is linear in both dimensions at ~20 µs per additional Node. 200 sibling Nodes compose in 4.5 ms — well under a single 16 ms frame.

Composition variants (all within noise of each other):

VariantMedian
Minimal Node~380 µs
Non-serializable state~380 µs
FullyWired (ListenFor + ReactTo + Intercept)~447 µs
With interceptor registration~400 µs
Recomposition via update {}~380 µs

Adding ListenFor, ReactTo, and Intercept to a Node adds ~65 µs. Serializable vs non-serializable state is within noise — the serializer lookup is cached.

Requesting Nodes (Provider dedup under composition):

CountMedianvs plain siblings
5694 µs+33%
10845 µs+14%
201.29 ms+64%
502.36 ms+69%

Multiple Nodes issuing the same DataImpulse share one in-flight provider job (structural equality dedup). The Request overhead is ~35 µs per Node on top of the base composition cost.

Derived initial state (parent state change cascading to children):

ChildrenMedianvs static initialState
5~540 µs+8%
10~740 µs+6%
20~940 µs+13%
50~1.59 ms+8%

Compose correctly scopes recomposition — changing a parent’s state only recomposes children whose inputs actually changed. No recomposition avalanche. Even in a nested chain where every level derives from the one above, the overhead is ~10-20% over static initial state.

Under realistic mixed workloads (simultaneous state broadcasts, impulse triggers, and data requests across multiple types), SwitchBoard throughput remains flat. Per-type flow isolation means different types don’t contend with each other.

  • ~200 ns overhead per SwitchBoard operation vs bare flows
  • ~20 ns per interceptor in the pipeline
  • ~20 µs per Node in Compose composition
  • Linear scaling in every dimension tested — no cliffs, no superlinear growth
  • Provider dedup works under composition load
  • Compose recomposition is correctly scoped through the Node tree
  • Testing — writing tests with SynapseTestRule