<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Benchmarks on Strata Documentation</title><link>https://danchupin.github.io/strata/architecture/benchmarks/</link><description>Recent content in Benchmarks on Strata Documentation</description><generator>Hugo</generator><language>en</language><atom:link href="https://danchupin.github.io/strata/architecture/benchmarks/index.xml" rel="self" type="application/rss+xml"/><item><title>GC + Lifecycle scaling</title><link>https://danchupin.github.io/strata/architecture/benchmarks/gc-lifecycle/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://danchupin.github.io/strata/architecture/benchmarks/gc-lifecycle/</guid><description>&lt;h1 id="gc--lifecycle-worker-scaling-benchmark-phase-1--phase-2"&gt;GC + Lifecycle worker scaling benchmark (Phase 1 + Phase 2)&lt;a class="anchor" href="#gc--lifecycle-worker-scaling-benchmark-phase-1--phase-2"&gt;#&lt;/a&gt;&lt;/h1&gt;
&lt;blockquote class='book-hint '&gt;
&lt;p&gt;Phase 2 (US-006) lands &lt;strong&gt;multi-leader&lt;/strong&gt; numbers below Phase 1&amp;rsquo;s single-leader
baseline. The two-section structure is intentional — Phase 1 measured the
per-leader concurrency cap, Phase 2 measures the multiplier from running N
replicas in parallel under &lt;code&gt;STRATA_GC_SHARDS=N&lt;/code&gt;.&lt;/p&gt;
&lt;/blockquote&gt;&lt;h2 id="phase-1--single-leader-concurrency-cap"&gt;Phase 1 — single-leader concurrency cap&lt;a class="anchor" href="#phase-1--single-leader-concurrency-cap"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Quantifies the throughput curve for &lt;code&gt;internal/gc.Worker&lt;/code&gt; and
&lt;code&gt;internal/lifecycle.Worker&lt;/code&gt; across the per-worker bounded-errgroup
fan-out introduced in cycle &lt;code&gt;ralph/gc-lifecycle-scale&lt;/code&gt; (US-001 / US-002).
The harness lands as &lt;code&gt;strata admin bench-gc&lt;/code&gt; + &lt;code&gt;strata admin bench-lifecycle&lt;/code&gt;
(US-003) and is wired into &lt;code&gt;make bench-gc&lt;/code&gt; / &lt;code&gt;make bench-lifecycle&lt;/code&gt; to drive
the canonical lab-tikv stack.&lt;/p&gt;</description></item><item><title>Meta-backend comparison</title><link>https://danchupin.github.io/strata/architecture/benchmarks/meta-backend-comparison/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://danchupin.github.io/strata/architecture/benchmarks/meta-backend-comparison/</guid><description>&lt;h1 id="meta-backend-benchmarks-tikv-vs-cassandra"&gt;Meta-backend benchmarks: TiKV vs Cassandra&lt;a class="anchor" href="#meta-backend-benchmarks-tikv-vs-cassandra"&gt;#&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;This page captures hot-path latency / throughput numbers for Strata&amp;rsquo;s two
production metadata backends (Cassandra and TiKV) and the in-tree memory
reference. The numbers are operator-runnable on a single laptop docker
stack via the harness in &lt;code&gt;internal/meta/storetest/bench.go&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The headline operations (US-018):&lt;/p&gt;
&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;Op&lt;/th&gt;
 &lt;th&gt;Why it matters&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;CreateBucket&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;LWT-equivalent create-if-not-exists&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;GetObject&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;Single Get / latest-version range-scan&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;ListObjects&lt;/code&gt; 100k page=1k&lt;/td&gt;
 &lt;td&gt;Listing throughput on a real-world bucket&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;CompleteMultipartUpload&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;LWT-equivalent status flip (&lt;code&gt;uploading→completing&lt;/code&gt;)&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;GetIAMAccessKey&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;SigV4 verifier — runs on every request&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;AuditAppend&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;Audit log write amplification&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;AuditSweepPartition&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;Periodic retention sweep (TiKV emulates Cassandra TTL)&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;RangeScanObjects&lt;/code&gt; 100k&lt;/td&gt;
 &lt;td&gt;TiKV-only: native ordered scan vs Cassandra fan-out&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="rig"&gt;Rig&lt;a class="anchor" href="#rig"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Single-laptop docker stack. Both backends run as 3-node clusters so LWT&lt;/p&gt;</description></item><item><title>Rebalance scaling</title><link>https://danchupin.github.io/strata/architecture/benchmarks/rebalance/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://danchupin.github.io/strata/architecture/benchmarks/rebalance/</guid><description>&lt;h1 id="rebalance-worker-scaling-benchmark-phase-2"&gt;Rebalance worker scaling benchmark (Phase 2)&lt;a class="anchor" href="#rebalance-worker-scaling-benchmark-phase-2"&gt;#&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;Closes ROADMAP P2 &lt;em&gt;&amp;ldquo;Rebalance worker not sharded — single goroutine
bottleneck on large deploys&amp;rdquo;&lt;/em&gt;. Mirrors the gc + lifecycle Phase 2 shape
(see &lt;a href="https://danchupin.github.io/strata/architecture/benchmarks/gc-lifecycle/#phase-2--multi-leader-us-006"&gt;GC + Lifecycle scaling&lt;/a&gt;
for the same fan-out pattern measured against gc and lifecycle workers).&lt;/p&gt;
&lt;p&gt;The single-leader rebalance worker scans every draining bucket per tick on
one goroutine. Phase 2 (&lt;code&gt;STRATA_REBALANCE_SHARDS=N&lt;/code&gt;) shards that scan by
&lt;code&gt;fnv32a(bucketID) % N&lt;/code&gt;; each replica races for one of the
&lt;code&gt;rebalance-leader-0..N-1&lt;/code&gt; leases and processes only its own shard&amp;rsquo;s bucket
subset. &lt;code&gt;STRATA_REBALANCE_SHARDS=1&lt;/code&gt; reproduces Phase 1 byte-for-byte.&lt;/p&gt;</description></item><item><title>Parallel chunk PUT + GET (RADOS)</title><link>https://danchupin.github.io/strata/architecture/benchmarks/parallel-chunks/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://danchupin.github.io/strata/architecture/benchmarks/parallel-chunks/</guid><description>&lt;h1 id="parallel-chunk-put--get-rados"&gt;Parallel chunk PUT + GET (RADOS)&lt;a class="anchor" href="#parallel-chunk-put--get-rados"&gt;#&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;Closes the two open &lt;code&gt;ROADMAP.md&lt;/code&gt; P2 entries:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Parallel chunk upload in &lt;code&gt;PutChunks&lt;/code&gt;&lt;/strong&gt; — sequential &lt;code&gt;for { ReadFull; writeChunk }&lt;/code&gt;
loop replaced with a bounded worker pool that dispatches chunk writes
concurrently. Manifest order + ETag (MD5 of the byte stream) are preserved.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Parallel chunk read / prefetch in &lt;code&gt;GetChunks&lt;/code&gt;&lt;/strong&gt; — sequential per-chunk fetch
replaced with a bounded prefetch reader. The next chunk is fetched while the
current one drains to the wire. Memory-bounded; aborts on client cancel.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The S3 data backend (&lt;code&gt;internal/data/s3/backend.go&lt;/code&gt;) is unaffected: the AWS SDK
&lt;code&gt;manager.Uploader&lt;/code&gt; already parallelises multipart uploads. Memory backend is
tests-only. Multi-cluster manifests (US-044) automatically benefit since
chunk-write dispatch is cluster-agnostic — the worker pool dials the right
ioctx per chunk via the existing &lt;code&gt;resolveClass&lt;/code&gt; / &lt;code&gt;ioctx&lt;/code&gt; helpers.&lt;/p&gt;</description></item><item><title>RGW comparison</title><link>https://danchupin.github.io/strata/architecture/benchmarks/rgw-comparison/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://danchupin.github.io/strata/architecture/benchmarks/rgw-comparison/</guid><description>&lt;h1 id="benchmarks-vs-ceph-rgw"&gt;Benchmarks vs Ceph RGW&lt;a class="anchor" href="#benchmarks-vs-ceph-rgw"&gt;#&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;This page captures the side-by-side numbers backing the README&amp;rsquo;s
&amp;ldquo;drop-in RGW replacement&amp;rdquo; claim. Closes ROADMAP P2 &lt;em&gt;&amp;ldquo;Benchmarks vs RGW&amp;rdquo;&lt;/em&gt;
via cycle &lt;code&gt;ralph/rgw-benchmarks&lt;/code&gt; (US-001..US-012); the post-fix rerun
landed via &lt;code&gt;ralph/p1-fixes&lt;/code&gt; (US-001..US-009) after the per-bucket
&lt;code&gt;bucket_stats&lt;/code&gt; LWT saturation was removed.&lt;/p&gt;
&lt;h2 id="headline-conclusion"&gt;Headline conclusion&lt;a class="anchor" href="#headline-conclusion"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Bucket-index claim — VERIFIED (provisionally) at the concurrency
RGW can sustain.&lt;/strong&gt; Two independent regimes surface the win:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;1 KiB PUT @ c=8&lt;/strong&gt; (the canonical &amp;ldquo;many small writes&amp;rdquo; hot path):
Strata p99 ≈ &lt;strong&gt;211 ms&lt;/strong&gt; vs RGW p99 &lt;strong&gt;11–22 s&lt;/strong&gt; (runs varied; one
run wedged at 364 s). Strata is &lt;strong&gt;~50× faster at p99&lt;/strong&gt; and stays
flat across the 3-run set; RGW&amp;rsquo;s omap-index serialisation surfaces
immediately past &lt;code&gt;c=1&lt;/code&gt; on the single-OSD lab. Same data tier
(single-OSD &lt;code&gt;ceph-a&lt;/code&gt; memstore), same &lt;code&gt;make up-bench-rgw&lt;/code&gt; shape — the
delta is gateway-side, not OSD.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ListObjects 100k-key @ c=8&lt;/strong&gt;: Strata sustains
&lt;strong&gt;~208 k ops/s @ p99 ~640 ms&lt;/strong&gt; across 3 runs, zero errors. RGW
could not be measured at this scale on the lima reference dev
box — the per-bucket pools &lt;code&gt;default.rgw.buckets.index&lt;/code&gt; saturate
the memstore OSD before the seed phase completes. The very fact
that RGW cannot complete the workload at the same lab shape
reinforces the bucket-index thesis: Strata&amp;rsquo;s sharded fan-out
(&lt;code&gt;s/B/&amp;lt;bid&amp;gt;/bs/&amp;lt;shard&amp;gt;&lt;/code&gt; × 8 shards on TiKV; sharded &lt;code&gt;objects&lt;/code&gt;
table on Cassandra) absorbs the same concurrent write pressure
RGW&amp;rsquo;s omap index falls over on.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;RGW wins at c=1 small PUT&lt;/strong&gt; as expected: Strata p99 ≈ &lt;strong&gt;12 ms&lt;/strong&gt;
vs RGW p99 ≈ &lt;strong&gt;2 ms&lt;/strong&gt;. The user-space SigV4 + policy-verify hop
Strata adds vs RGW&amp;rsquo;s in-process auth costs ~10 ms on the
single-threaded hot path; the gap closes as soon as concurrency
arrives because the gateway-side per-request cost stops dominating
relative to backend serialisation.&lt;/p&gt;</description></item><item><title>RADOS ReadOp / WriteOp batching</title><link>https://danchupin.github.io/strata/architecture/benchmarks/rados-ops/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://danchupin.github.io/strata/architecture/benchmarks/rados-ops/</guid><description>&lt;h1 id="rados-readop--writeop-batching"&gt;RADOS ReadOp / WriteOp batching&lt;a class="anchor" href="#rados-readop--writeop-batching"&gt;#&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;Closes the &lt;code&gt;ROADMAP.md&lt;/code&gt; P3 entry &lt;strong&gt;ReadOp / WriteOp batching in RADOS&lt;/strong&gt;
(US-003 of &lt;code&gt;ralph/storage-correctness&lt;/code&gt;).&lt;/p&gt;
&lt;h2 id="what-batching-does"&gt;What batching does&lt;a class="anchor" href="#what-batching-does"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;internal/data/rados/ops.go&lt;/code&gt; (build tag &lt;code&gt;ceph&lt;/code&gt;) defines two helpers that
bundle a chunk Write / Read with N xattr ops into a single librados
operation:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;writeChunkBatched(ioctx, oid, body, xattrs)&lt;/code&gt; — builds a &lt;code&gt;goceph.WriteOp&lt;/code&gt;,
appends &lt;code&gt;WriteFull(body)&lt;/code&gt; + &lt;code&gt;SetXattr(k, v)&lt;/code&gt; per entry of &lt;code&gt;xattrs&lt;/code&gt;, then
&lt;code&gt;Operate()&lt;/code&gt;s once. xattrs nil ⇒ byte-identical to the legacy &lt;code&gt;writeChunk&lt;/code&gt;
in &lt;code&gt;backend.go&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;readChunkBatched(ioctx, oid, off, length, wantXattrs)&lt;/code&gt; — builds a
&lt;code&gt;goceph.ReadOp&lt;/code&gt; with &lt;code&gt;Read(off, buf)&lt;/code&gt;, then &lt;code&gt;Operate()&lt;/code&gt;s once. When
&lt;code&gt;wantXattrs&lt;/code&gt; is true a follow-up &lt;code&gt;ioctx.ListXattrs&lt;/code&gt; runs to populate the
xattrs map — go-ceph v0.39 does not expose &lt;code&gt;rados_read_op_getxattrs&lt;/code&gt;, so
xattrs sit on a second client round-trip. Today no caller requests
xattrs.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;code&gt;writeChunk&lt;/code&gt; (legacy) and &lt;code&gt;writeChunkBatched(_, _, _, nil)&lt;/code&gt; produce the
same on-wire librados &lt;code&gt;WriteOp{ WriteFull }&lt;/code&gt;. The win materialises only
when xattrs are added to the PUT hot path — a future cycle. The helpers
exist now so the call sites are wired and the bench shape is established.&lt;/p&gt;</description></item><item><title>RADOS conn-pool sizing</title><link>https://danchupin.github.io/strata/architecture/benchmarks/rados-pool/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://danchupin.github.io/strata/architecture/benchmarks/rados-pool/</guid><description>&lt;h1 id="rados-conn-pool-sizing"&gt;RADOS conn-pool sizing&lt;a class="anchor" href="#rados-conn-pool-sizing"&gt;#&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;Closes the &lt;code&gt;ROADMAP.md&lt;/code&gt; P3 entry &lt;strong&gt;Connection pool tuning&lt;/strong&gt;
(US-004 of &lt;code&gt;ralph/storage-correctness&lt;/code&gt;).&lt;/p&gt;
&lt;h2 id="what-the-pool-does"&gt;What the pool does&lt;a class="anchor" href="#what-the-pool-does"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;A single librados &lt;code&gt;*Conn&lt;/code&gt; serialises ops through one cephx session and a
per-conn thread pool. Write-heavy workloads that saturate that single
session see contention even though the OSD layer has headroom. The
&lt;code&gt;connPool&lt;/code&gt; in &lt;code&gt;internal/data/rados/pool.go&lt;/code&gt; (build tag &lt;code&gt;ceph&lt;/code&gt;) holds N
pre-connected &lt;code&gt;*goceph.Conn&lt;/code&gt; instances per cluster and serves them
round-robin via an atomic counter; per-conn IOContexts are cached
lazily by &lt;code&gt;(pool, namespace)&lt;/code&gt;.&lt;/p&gt;</description></item><item><title>OTel ring-buffer bytes budget</title><link>https://danchupin.github.io/strata/architecture/benchmarks/otel-ringbuf/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://danchupin.github.io/strata/architecture/benchmarks/otel-ringbuf/</guid><description>&lt;h1 id="otel-ring-buffer-bytes-budget"&gt;OTel ring-buffer bytes budget&lt;a class="anchor" href="#otel-ring-buffer-bytes-budget"&gt;#&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;Closes the &lt;code&gt;ROADMAP.md&lt;/code&gt; P3 entry &lt;strong&gt;OTel ring-buffer eviction tuning
under burst load&lt;/strong&gt; (US-005 of &lt;code&gt;ralph/storage-correctness&lt;/code&gt;).&lt;/p&gt;
&lt;h2 id="what-the-ring-buffer-does"&gt;What the ring buffer does&lt;a class="anchor" href="#what-the-ring-buffer-does"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;internal/otel/ringbuf.RingBuffer&lt;/code&gt; is an in-process &lt;code&gt;SpanProcessor&lt;/code&gt;
that retains every finished span under an LRU + bytes-budget. The
&lt;code&gt;/admin/v1/diagnostics/trace/{requestID}&lt;/code&gt; admin endpoint reads from
the ring so operators can debug a request without a Jaeger / Tempo
deployment. Tail sampling on the exporter side still drops most spans
on the wire — the ring keeps the full payload locally.&lt;/p&gt;</description></item><item><title/><link>https://danchupin.github.io/strata/architecture/benchmarks/data/gc-lifecycle-phase-2/README/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://danchupin.github.io/strata/architecture/benchmarks/data/gc-lifecycle-phase-2/README/</guid><description>&lt;h1 id="phase-2--gc--lifecycle-multi-leader-bench-artifacts"&gt;Phase 2 — gc + lifecycle multi-leader bench artifacts&lt;a class="anchor" href="#phase-2--gc--lifecycle-multi-leader-bench-artifacts"&gt;#&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;JSONL captured by the bench harness in &lt;strong&gt;in-process simulation mode&lt;/strong&gt;:
both meta and data backends are pure-memory; the multi-shard / multi-
replica race happens inside one &lt;code&gt;strata admin&lt;/code&gt; process via the &lt;code&gt;--shards&lt;/code&gt;
(gc) / &lt;code&gt;--replicas&lt;/code&gt; (lifecycle) flags wired in US-006.&lt;/p&gt;
&lt;h2 id="files"&gt;Files&lt;a class="anchor" href="#files"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;File&lt;/th&gt;
 &lt;th&gt;What&lt;/th&gt;
 &lt;th&gt;How to regenerate&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;sim-bench-gc-shards1.jsonl&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;gc bench, single-leader (Phase 1 shape), N=50000, c∈{1,4,16,64,256}&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;for c in 1 4 16 64 256; do STRATA_META_BACKEND=memory STRATA_DATA_BACKEND=memory ./bin/strata admin bench-gc --entries=50000 --concurrency=$c --shards=1; done | jq -c .&lt;/code&gt;&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;sim-bench-gc-shards3.jsonl&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;gc bench, 3-shard (Phase 2 shape), N=50000&lt;/td&gt;
 &lt;td&gt;…&lt;code&gt;--shards=3&lt;/code&gt;&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;sim-bench-lifecycle-replicas1.jsonl&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;lifecycle bench, single-replica (Phase 1), N=10000, 1 bucket&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;for c in …; do … bench-lifecycle --objects=10000 --concurrency=$c --replicas=1 --buckets=1; done&lt;/code&gt;&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;sim-bench-lifecycle-replicas3.jsonl&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;lifecycle bench, 3-replica (Phase 2), N=10000, 9 buckets&lt;/td&gt;
 &lt;td&gt;…&lt;code&gt;--replicas=3 --buckets=9&lt;/code&gt;&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="caveats"&gt;Caveats&lt;a class="anchor" href="#caveats"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Memory meta + memory data put the worker on a fast path with effectively
zero per-op latency. Concurrency speedup that the production lab observes
on TiKV (real pessimistic-txn round-trips) does NOT manifest here — the
in-process Go RWMutex is the bottleneck. Treat these numbers as a noise
floor that pins the &lt;strong&gt;shape of multi-leader coordination overhead&lt;/strong&gt;, not
as a forecast of production throughput.&lt;/li&gt;
&lt;li&gt;For the canonical Phase 2 numbers operators should rerun
&lt;code&gt;make bench-gc-multi&lt;/code&gt; / &lt;code&gt;make bench-lifecycle-multi&lt;/code&gt; against the
3-replica lab brought up via &lt;code&gt;make up-lab-tikv-3&lt;/code&gt; (see
&lt;code&gt;docs/site/content/architecture/benchmarks/gc-lifecycle.md&lt;/code&gt;&amp;rsquo;s &amp;ldquo;Phase 2 — multi-leader&amp;rdquo; section).&lt;/li&gt;
&lt;li&gt;Every JSON object on a line is one bench level (one &lt;code&gt;(--concurrency, --shards|--replicas)&lt;/code&gt; combination). Schema matches &lt;code&gt;cmd/strata/admin/ bench_common.go::benchResult&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;</description></item></channel></rss>