There are no published numbers yet. Here's everything else.
A page with no numbers on it invites the assumption that the numbers are bad. The truthful position is narrower than that: AnimusDB has not been benchmarked at scale, so any figure we published today would be measuring an unfinished storage path — and would be quoted back at us for years.
What we can give you now is the cost model, which is derived from the architecture rather than measured, so you can check it against the design instead of trusting us — and the measurement method and the load generator, which are built and in the repository, so you can check how any number will be produced before there is one.
What each operation actually costs, in round trips.
| Operation | Network | Disk | Hard floor |
|---|---|---|---|
| Write to one tablet | One Raft round trip to a quorum | A durable append on each replica in the quorum | The round trip to the slowest replica in the fastest quorum, plus one flush |
Read, ConsistentRead: true | Served by the tablet leader | A local read | Client-to-leader latency |
Read, ConsistentRead: false | Need not involve the leader | A local read | Client-to-nearest-replica latency |
| Transaction across N tablets | Two-phase commit across N Raft groups | Durable appends in each | Two consensus rounds, bounded by the slowest participating group |
Query within a partition | One tablet | A range read | As above, per page |
Scan | Every tablet holding the table | A full pass | Proportional to the data, as on any database |
The floors in that last column are physics, not implementation. A quorum write cannot be acknowledged before the network has carried it to a quorum. Put replicas in three availability zones and your write floor is a metro round trip; put them on three continents and it is a continental one. No consensus protocol repeals this, and a vendor claiming otherwise is measuring something else.
The corollary is the useful part: most of your latency budget is a placement decision, and placement is yours to make. That is the same lever a managed service takes away from you.
What adding hardware buys, and what it doesn't.
Scales with the cluster
- Aggregate throughput. Tablets are independent Raft groups with independent leaders. More tablets on more nodes means more leaders doing work in parallel.
- Capacity. A joining node takes on tablets by rebalancing, online, without a maintenance window.
- Fault isolation. A node's failure affects the tablets it led, not the cluster.
Doesn't
- A single tablet. One leader, one quorum. The unit of parallelism is the tablet, so the tablet is also the ceiling.
- A hot partition key. Everything for one key lives in one tablet. This is true of DynamoDB too, and the same modelling fixes apply.
- Cross-tablet transactions. Two-phase commit costs more than a single-group write and always will. Use it deliberately.
- Topology churn. The control plane is one Raft group. It is off the request path, but it does bound how fast the map itself can change.
Six questions worth more than someone else's benchmark.
A published benchmark measures a workload that isn't yours on hardware you don't have. If you are evaluating seriously, these are the questions that actually determine what you'll see.
- Where do the three replicas of a tablet sit? Same rack, same zone, or three zones? This sets your write floor before any code runs.
- What fraction of your reads genuinely need linearizability? On most workloads it is far less than 100%, and every one you can relax skips the leader.
- How many of your writes cross a tablet boundary? Each one is a two-phase commit. If the answer is "most of them", revisit the key design before revisiting the database.
- What is your item size distribution? Consensus cost is per-entry; bytes are per-byte. The two scale differently and the crossover matters.
- What does your disk do under
fsync? Durability is a flush on every replica in the quorum. Cheap network storage will dominate everything else on this page. - How many tablets will your table have? That number is your parallelism, and it is a function of data volume and split thresholds.
You can answer the last four today by running a three-node cluster against a copy of your real traffic. That is a better afternoon than reading anyone's numbers.
The method is built. The numbers are not.
The load generator is animus-bench, a separate client that drives a cluster over the real DynamoDB wire — HTTP/1.1 JSON, every request SigV4-signed — not an in-process shortcut. The full procedure is in docs/benchmarks.md and the design record is ADR 0076.
What it does
- YCSB A–F mapped onto DynamoDB operations:
GetItem,UpdateItem,PutItem,Query, and workload F'sGetItemplus a conditionalUpdateItem. Zipfian or uniform keys; record count and item size are fixed flags and are written into the results. - Open-loop arrivals. Operation i is scheduled at
start + i/ratewhatever the server is doing, and latency is measured from that intended time, so a stall is charged to every request that should have been sent during it (coordinated-omission correction). The latency a closed-loop client would have seen is recorded beside it, so you can see how much the correction matters. - HdrHistogram latency to three significant figures: p50, p90, p99, p99.9, p99.99 and max per operation class. Errors are counted by kind, not folded into latency; operations the client could not even start are reported as abandoned, never dropped.
ConsistentRead: trueandfalseare separate runs on the same seeded operation stream, never blended.- Phases: load, a discarded warm-up, steady state (or a throughput sweep to find the knee), then a degraded run — the tablet leader, a follower or a chosen node is killed mid-run, with a healthy baseline before it and a recovery phase after — on the whole workload mix.
- A results file (
animus-bench/v1JSON) with the git SHA, exact command line, seed, client host, cluster topology and replica placement read back from/admin, and the methodology itself.
What it does not do (yet)
- TLS is opt-in and server-only. With
--tls-cathe generator verifies each node over TLS (no client certificate) and the results file recordstls: true; without it, plain TCP andtls: false. No TLS-on versus TLS-off comparison has been published yet, so state which one a number is. - Workload E is not YCSB's scan. A DynamoDB
Querycannot cross partition keys, so E is a shortQueryinside one 100-record partition. It measures a range read on one tablet, not a cross-partition scan. - Encryption at rest and
--shared-walare not reported by/admin, so an external run records them as unknown and the publisher has to state them. - Nothing about the servers' hardware is detected. The tool records the client host; instance type, disk and network of the cluster are stated alongside the file.
- Not measured at all: cross-partition
Scan, transactions, batch operations, secondary indexes, Streams and TTL overhead, backup overhead. - The separate-hosts topology is supported but has never been run. Only same-host development runs have.
What counts as a publishable run. The generator and the cluster must be on different hosts, and the file must contain a degraded run whose fault was actually injected. A run where the tool launched the cluster itself, where every endpoint is a loopback address, or that has no such degraded run is marked "publishable": false in its own output, with every unmet condition listed. That flag is a necessary condition, not a certificate — it does not check the rest, which we require before publishing: three nodes at replication factor 3 as the baseline plus one scale-out point, a named instance type, disk model and network for both sides, the leader-kill and follower-kill runs present, and the raw JSON committed or attached to a release.
Regression tracking is deliberately modest. A manually triggered workflow builds a base and a candidate and runs both on the same host, interleaved (base, head, base, head…), and a compare step reports each metric's run-to-run spread. A change is flagged only when it is larger than a stated threshold (10% by default) and the base and candidate ranges do not overlap; otherwise it is shown as noisy. It reports and never fails the job; a lone outlier is a rerun, not a verdict. A benchmark is never a pass/fail latency assertion in a test, and a trend line needs a dedicated, fixed runner that does not exist yet.
The rules we committed to before we had results.
Publishing the methodology first is a way of making it expensive to cherry-pick later. Where each rule stands today is in the right-hand column.
| Commitment | What it means | Where it stands |
|---|---|---|
| Disclosed hardware | Instance types or machine specs, disk model, network topology, and the placement of every replica. | Replica placement and the client host are captured into the results file. Server instance type, disk and network are stated by whoever publishes the run; the tool does not detect them. |
| Tail latency, not averages | p50, p99 and p99.9 for each operation class. A mean latency figure for a distributed database is close to meaningless. | Built: p50 to p99.99 and max per operation class, measured from the intended send time. |
| Both read modes, separately | Linearizable and eventually-consistent reads reported apart, never blended into one number. | Built: each read workload runs once per mode. |
| A failure case in every run | Numbers taken while a node is down, and during a leader election, not only on a healthy cluster. | Built: a leader-, follower- or node-kill run with baseline, degraded and recovery phases. It needs a way to kill a node; without one the run is skipped and the file says so. |
| Reproducible | Workload definitions, configuration and raw output in the repository, so you can re-run them. | The generator, workload definitions, seed and results format are in the repository. A hardware run has not been done, so there is no raw output from one to commit yet. |
| No comparison charts against DynamoDB | Comparing self-hosted hardware to a metered managed service produces whichever answer the author wanted. We're not going to do it. | Unchanged. The tool makes no comparison, and its results say so. |
You can run the generator yourself today against a cluster you start (cargo run --release -p animus-bench -- --help). If it launches the cluster on the same machine it will say publishable: false, and you should read that as meaning it: such figures measure your machine, not the database. Colocated development runs have also shown write-path stalls of a few hundred milliseconds and a roughly 21 ms floor on ConsistentRead: true reads; these are observations from a development machine, not results, and are being tracked as issues. cargo bench -p animusd is a separate, older in-process smoke — unauthenticated, closed-loop, no coordinated-omission correction — and its numbers are not comparable to the generator's.
None published yet.
There is no results table on this page because we do not have a result we are willing to put one beside. The only runs so far were on a development machine with the load generator and the servers sharing it, which the tool itself marks non-publishable, and a figure from such a run would measure that machine.
The first curated run needs a dedicated client host and a real multi-host cluster of named hardware, and it will be the first time the separate-hosts path is exercised end to end. When it exists, this section will carry the raw results files, the three-node baseline and a scale-out point, the leader-kill and follower-kill runs, the hardware named in full, and the exact command lines.