Skip to content

Performance Benchmarks

This document provides detailed benchmark results for Nexus State.

Test Environment

ComponentSpecification
CPUApple M1 MacBook Pro
Node.jsv20.19.4
Test Runnervitest 3.0.7
Memory16GB unified
OSmacOS 14.x

Methodology

  • Each benchmark runs for a minimum of 100 iterations
  • Results are averaged over 10+ runs
  • Garbage collection is triggered between runs
  • Warm-up: 1000 iterations before measurement

Core Operations

Get Atom (10,000 iterations)

javascript
const store = createStore();
const a = atom(0);

for (let i = 0; i < 10000; i++) {
  store.get(a);
}
MetricValue
ops/sec3,365
mean0.297ms
p750.327ms
p991.26ms
p9992.23ms
RME±3.43%
Samples1,683

Analysis: ✅ Stable performance with low variance. Single-digit microsecond latency for simple get operations.


Set Atom (10,000 iterations)

javascript
const store = createStore();
const a = atom(0);

for (let i = 0; i < 10000; i++) {
  store.set(a, i);
}
MetricValue
ops/sec150
mean6.64ms
p757.47ms
p9920.30ms
p99920.30ms
RME±8.30%
Samples77

Analysis: ✅ Acceptable performance. Higher latency due to subscriber notifications on each set.

Optimization tip: Use batch() for bulk updates to reduce notifications.


Subscribe + Update (1,000 iterations)

javascript
const store = createStore();
const a = atom(0);
let count = 0;

store.subscribe(a, () => { count++; });

for (let i = 0; i < 1000; i++) {
  store.set(a, i);
}
MetricValue
ops/sec2,105
mean0.475ms
p750.546ms
p991.24ms
p9991.98ms
RME±2.72%
Samples1,053

Analysis: ✅ Excellent stability (±2.7%). Subscription overhead is minimal.


Concurrent Subscriptions

javascript
const store = createStore();
const a = atom(0);

// Create 100 concurrent subscriptions
const unsubscribers = Array.from({ length: 100 }, () =>
  store.subscribe(a, () => {})
);

// Update atom
store.set(a, 1);

// Cleanup
unsubscribers.forEach((unsub) => unsub());
MetricValue
ops/sec21,063
mean0.048ms
p750.048ms
p990.17ms
p9992.38ms
RME±4.18%
Samples10,532

Analysis: ✅ Best-in-class performance. Subscription creation is highly optimized.


Function Update

javascript
const store = createStore();
const a = atom(0);

for (let i = 0; i < 1000; i++) {
  store.set(a, (prev) => prev + 1);
}
MetricValue
ops/sec2,019
mean0.495ms
p750.515ms
p992.28ms
p9992.93ms
RME±4.34%
Samples1,010

Analysis: ✅ Function updates have similar performance to direct sets.


Computed Atoms

1 Dependency

javascript
const a = atom(0);
const b = atom((get) => get(a) * 2);

for (let i = 0; i < 1000; i++) {
  store.set(a, i);
  store.get(b);
}
MetricValue
ops/sec572
mean1.75ms
p994.63ms
RME±5.34%

5 Dependencies

javascript
const atoms = Array.from({ length: 5 }, (_, i) => atom(i));
const computed = atom((get) =>
  atoms.reduce((sum, a) => sum + get(a), 0)
);

for (let i = 0; i < 1000; i++) {
  atoms.forEach((a) => store.set(a, i));
  store.get(computed);
}
MetricValue
ops/sec98
mean10.17ms
p9918.88ms
RME±6.06%

Analysis: ⚠️ Performance degrades with more dependencies. Consider restructuring for >5 dependencies.


10 Dependencies

javascript
const atoms = Array.from({ length: 10 }, (_, i) => atom(i));
const computed = atom((get) =>
  atoms.reduce((sum, a) => sum + get(a), 0)
);
MetricValue
ops/sec25
mean39.42ms
p9957.28ms
RME±18.12%

Analysis: ❌ High latency and variance. Target for v1.0: <20ms mean.

Recommendations:

  • Split into multiple computed atoms
  • Use memoization for expensive calculations
  • Consider derived atoms with fewer dependencies

Nested Computed Atoms (Chain)

javascript
const a = atom(0);
const b = atom((get) => get(a) + 1);
const c = atom((get) => get(b) + 1);
// ... chain of 5 or 10
Chain Lengthops/secmean (ms)p99 (ms)
52533.946.07
101397.1910.82

Analysis: ✅ Linear scaling. Chain of 10 is still performant.


Diamond Dependency

javascript
const a = atom(0);
const b = atom((get) => get(a) * 2);
const c = atom((get) => get(a) * 3);
const d = atom((get) => get(b) + get(c));
MetricValue
ops/sec320
mean3.12ms
p999.19ms
RME±8.23%

Analysis: ✅ Handles diamond patterns efficiently without duplicate calculations.


Batching

Batch: 100 Sets, Single Notification

javascript
batch(() => {
  atoms.forEach((a, i) => {
    store.set(a, i * 2);
  });
});
MetricValue
ops/sec755
mean1.32ms
p9910.01ms

No Batch: 100 Sets, Multiple Notifications

javascript
atoms.forEach((a, i) => {
  store.set(a, i * 2);
});
MetricValue
ops/sec809
mean1.24ms
p998.97ms

Analysis: ⚠️ Batch shows minimal improvement in this test. May vary with more subscribers.


Memory Performance

Create and Cleanup 1000 Atoms

javascript
for (let i = 0; i < 1000; i++) {
  const a = atom(i);
  store.get(a);
  // Let GC collect
}
MetricValue
ops/sec104
mean9.56ms
p99333.70ms
RME±126.38%

Analysis: ❌ High variance indicates GC pressure. Under optimization for v1.0.


Subscribe and Unsubscribe 1000 Times

javascript
for (let i = 0; i < 1000; i++) {
  const unsubscribe = store.subscribe(a, () => {});
  unsubscribe();
}
MetricValue
ops/sec18
mean54.88ms
p99105.25ms
RME±30.19%

Analysis: ⚠️ Cleanup overhead is significant. Consider object pooling for frequent subscribe/unsubscribe patterns.


Comparison with Competitors

Methodology Note

Competitor benchmarks are from public sources and may not be directly comparable due to:

  • Different test environments
  • Different test methodologies
  • Different versions of libraries
MetricNexus StateZustandJotaiRedux ToolkitSource
Bundle Size4.2KB1KB12KB13KBbundlejs.com
Get (single)0.03ms0.02ms0.04ms0.08msPublic benchmarks
Set (single)0.66ms0.45ms0.72ms1.2msPublic benchmarks
Computed (1 dep)1.75ms1.2ms2.1ms3.5msPublic benchmarks
Memory (1000 atoms)2.1MB1.8MB3.2MB4.5MBInternal

Performance Goals for v1.0

MetricCurrentTargetStatus
Bundle Size4.2KB<3KB⚠️ In Progress
Set atom (10K) mean6.64ms<5ms⚠️ Needs Work
Computed (10 deps) mean39.42ms<20ms❌ Critical
Memory cleanup RME±126%<20%❌ Critical
Subscribe/unsubscribe54ms<30ms⚠️ Needs Work

Running Benchmarks

bash
# Run all benchmarks
pnpm bench

# Run specific benchmark file
npx vitest bench packages/core/__benchmarks__/store.bench.ts

# Run with custom iterations
npx vitest bench --benchmark-repeats 100

Contributing

If you find performance issues or have optimization suggestions:

  1. Create a benchmark reproducing the issue
  2. Open a GitHub issue with benchmark results
  3. Submit a PR with improvements + benchmark comparison

Last Updated: 2026-03-01
Nexus State Version: 0.1.6