Files
zeekayandHanzo Dev 4fdedc5f54 Every benchmark in one repository
The measurement lanes lived in hanzoai/cloud/bench, which meant cloning the
thing being measured to run anything — including lanes that measure no binary
at all. They are here now, at the root, beside the load and scale harnesses
that were already here: eleven lanes, MEASURED.md for what each found,
naive.md for what competitors publish and where it was read.

Four lanes still need the cloud source, because they measure a binary rather
than a library. `cloud_src` in host.sh finds it — $CLOUD_SRC, then ../cloud —
or prints how to get one. It does not clone: a benchmark that fetches its own
subject decides which revision you measured.

AND IT SAYS WHICH SOURCE IT FOUND. hanzoai/cloud and hanzo-inc/cloud are
different repositories that both check out as `cloud`, and self/modules.sh
reads 127 modules on one and 55 on the other. Neither is wrong about the tree
it was handed; a lane that does not name its subject is. It prints path, remote
and commit now, the way every timing prints its host.

Fixed on the way: egress reached for bench/egress/catcher.py and transport for
./bench/transport/harness, both paths in the repository they left. The harness
builds from this module now — its only dependency is zap-proto/zip — and
market/bench.mjs and brain/tables.mjs lost a directory level each.

Verified from the new root: fleet reproduces 454.6 MB and 477 bytes per agent,
and self/modules.sh reproduces 127 of 127 when pointed at the tree the figure
came from.

Co-authored-by: Hanzo Dev <[email protected]>
2026-09-16 09:51:20 -07:00

3.2 KiB
Raw Permalink Blame History

hanzoai/benchmarks — unified benchmark + load framework for Hanzo cloud products

One place to prove what the cloud stack does under load and at scale. Before this, cloud-product benchmarks did not exist as a framework — perf work was scattered across unrelated repos (engine-v4bench, enso-bench, lux/benchmarks, zap/bench, GPU/ consensus/model harnesses). This is the home for api.hanzo.ai / the hanzoai/cloud unified binary and its subsystems (gateway, ai, kms, commerce, iam, …).

Layout

cloud/<suite>/      Go property + micro benchmarks that need no cluster (fast, CI-able)
  shard/            horizontal writer-scale routing (hanzoai/ha HRW/rendezvous)  ✅
k3s/                local N-pod INTEGRATION harness (k3s is installed at /usr/local/bin/k3s)
load/               HTTP/gRPC load profiles (k6 / ghz) — wired when the tools are present

Two tiers, on purpose:

  • Property/micro (cloud/<suite>) — pure Go, deterministic, runs in seconds, proves an invariant (e.g. one-owner-per-org) and measures a primitive (routing ns/op). No cluster, so it runs in CI on every PR.
  • Integration (k3s/) — stands the real StatefulSet up locally and drives end-to-end load, so throughput scaling and failover are measured against the actual binary.

Run

make scale     # print the horizontal-scale proof (1M tenants across N=3/10/100 pods)
make bench     # routing throughput (ns/op, allocs) across ring sizes
make k3s-up    # (integration) stand up cloud StatefulSet N=3 in local k3s
make k3s-down

What the shard suite proves (why horizontal scale is safe)

cloud/shard benchmarks the exact routing primitive the in-binary shard router uses — hanzoai/ha HRW/rendezvous org→owner election — the thing that guarantees no two pods ever write one tenant's SQLite file (the unrecoverable failure). Measured over 1,000,000 tenants (see make scale):

N pods per-pod mean stddev max skew verdict
3 333,333 0.05% 0.10% dead-even
10 100,000 0.31% 1.05% even
100 10,000 0.98% 4.46% even
  • One owner per org, deterministic — 100k orgs × 6 re-elections all agree → the no-dual-writer invariant holds mathematically (TestDeterministicSingleOwner).
  • Even load — 0.05% stddev at N=3 → no hot shard → write capacity scales ~linearly (per-org SQLite has no shared lock).
  • Minimal rebalance — growing 4→5 pods remaps only 20.1% of tenants (ideal 20%), so a scale-up moves the fewest tenant files (TestMinimalReshuffleOnScale).
  • Routing tax — ~545 ns/op at N=3 (~1.8M routes/sec/core); scales O(N) per lookup.

Finding (benchmark-driven)

ha.Owner allocates O(N) per election (5 allocs @ N=3 → 102 @ N=100). Negligible at the target N=3, but an allocation-free rendezvous in hanzoai/ha would help large rings — a tracked optimization, not a blocker.

Adding a suite

Drop cloud/<name>/<name>_test.go with Benchmark* (perf) and Test*ScaleProof-style property tests that print with -v. Keep it cluster-free where possible; push end-to-end load into k3s/.