The whole system, on one page.
What it's compatible with, how it's built, how it's tested, what it costs you in round trips, and how you run it. Each section stops where the reference page begins.
On this page
It speaks DynamoDB, so your SDK doesn't know the difference.
Tables of items addressed by a partition key and an optional sort key, with schemaless attributes — the model you already design for. Working today: PutItem, GetItem, UpdateItem, DeleteItem with condition and update expressions; Query and Scan with filters, pagination and index queries; the batch operations; transactions; secondary indexes added and dropped online with backfill; streams; TTL.
Four differences worth knowing before you assume a drop-in: scans are ordered by token rather than partition-key value; provisioned throughput is enforced as real admission control (RCUs/WCUs, ProvisionedThroughputExceededException included) but there is no billing meter behind it — no invoice, no auto-scaling; credentials are verified only when the opt-in SigV4 check is switched on — by default any caller that can reach the port is trusted; and the AWS-side integrations — Lambda triggers, DAX, CloudWatch — have no equivalent.
Two planes, one Raft group per tablet, no special node.
A small Raft group holds cluster metadata: membership, which node owns which tablet, what tables exist. It is written to when the topology changes, which is rare against your request rate, and it is not on the path of your reads and writes.
Your data lives in as many independent Raft groups as you have tablets, each replicated and led separately. A tablet is a contiguous range of the token space, and it is the unit of replication, movement and consensus. When one grows past its threshold it splits, online, into two groups.
Nothing funnels through a single log and no node is special — so losing one costs you an election on the tablets it led, not the cluster.
| Operation | Guarantee |
|---|---|
| Single-tablet write | Linearizable, via that tablet's Raft leader |
ConsistentRead: true | Linearizable, served by the leader |
ConsistentRead: false | Eventually consistent, need not involve the leader |
| Multi-tablet transaction | Serializable, via 2PC with hybrid-logical-clock timestamps and MVCC snapshot reads |
The cluster runs inside a deterministic simulator.
Everything that could vary between runs — the clock, the network, the disk, scheduling, random numbers — goes through an abstraction. In production that is the operating system; under test it is a deterministic stand-in, so a whole cluster runs in one process, faster than real time, with partitions, crashes, clock skew and disk faults injected on purpose.
Because nothing varies except the seed, a failing run is described by a single number and replays exactly. That turns the expensive half of a distributed-systems bug — reproducing it — into a constant.
It is not a proof, and it only covers the faults that were modelled. The article below draws that boundary properly, and gives you six questions to interrogate anyone making this claim, us included.
No benchmarks yet — but the cost model is knowable.
AnimusDB has not been benchmarked at scale, so it makes no performance claims. Publishing a number today would measure an unfinished storage path and then be quoted back at us for years.
What the architecture does fix is the shape of the cost. A write is one Raft round trip to a quorum plus a durable local write, so it cannot be acknowledged before the network has carried it to that quorum — put replicas in three availability zones and your write floor is a metro round trip. A linearizable read is served by the tablet leader; an eventually-consistent one need not be. A transaction across tablets is two-phase commit, and costs accordingly.
Throughput scales with tablet count, because tablets are independent groups with independent leaders. It does not scale within one tablet, and a hot partition key is still a hot partition key — exactly as on DynamoDB.
The full cost model, and what we'll publishOne binary, four shapes, six ports.
Every node is the same animusd binary; what differs is which planes it hosts, and that is a line in a config file. Run combined nodes by default, split into control-only and data-only as a cluster grows, or start an entire cluster in a single process for development. A config can mix shapes, so a cluster migrates between them incrementally rather than being rebuilt.
A node claims six consecutive ports from its base, 7100 by default: Raft traffic, the client protocol, the DynamoDB HTTP endpoint (which also serves GET /metrics), the admin API and dashboard, intra-cluster communication and a data console.
Day two, available
- Growing: a joining node needs the intra-cluster address of any running node
- Shrinking:
drain,drain-status,decommission - Node failure: replicas re-created automatically, no operator action
- On-demand backup and restore to a new table (DynamoDB's own
CreateBackup/RestoreTableFromBackup) - Continuous backups (point-in-time recovery to any second,
UpdateContinuousBackups/RestoreTableToPointInTime) - Export a table's data to a customer-named S3 bucket in DynamoDB's own JSON layout (
ExportTableToPointInTime), and import it back into a brand-new table (ImportTable) — either this adapter's own export, or real AWS's identical layout - Metrics, OpenTelemetry tracing, admin JSON endpoints and a built-in dashboard
- Rolling upgrades — a node-by-node roll with
animus cluster roll plan|wait|statusandanimus cluster finalize, or on Kubernetes from aspec.imageedit, with the operator rolling pods one at a time behind a health gate (not yet safe from an older release while multi-item transactions are in use)
Day two, missing
- Authentication beyond SigV4 — TLS (below) adds encryption and, on the internal ports, cluster-membership authentication, but caller identity on the client port is still just opt-in SigV4
TLS is available on every port — mutual on the Raft/intra-cluster ports, server-only on the client, admin and console ports — config-gated per cluster and off by default.
Encryption at rest is available too, via a key file (--encryption-key PATH, or the same field in a cluster config) — or, on Kubernetes, spec.encryptionKeySecretName naming a pre-existing Secret the operator mounts read-only: every AEAD-sealed byte covers the Raft WAL and each hosted tablet's own engine files, with a wrong or missing key against an already-encrypted data directory refused loudly at startup rather than silently reset. It also covers backup, point-in-time-recovery and stream segment objects on every segment/backup store — the default replicated one included, not just the fs:/s3:// opt-ins — as long as every node sharing a store is configured with the identical key file (a cluster-wide key, not a per-node one, since a different node routinely reads what another wrote). There's no key rotation yet and it is not supported: the key is cluster-wide, so a differently-keyed replica cannot read the shared stores, and changing a key means building a new cluster; a keyring-based design is planned. It's off by default either way.
A cluster with no TLS configured is exactly as before: plain TCP everywhere. Turn it on and the internal ports refuse a non-cluster-member outright; the client port still only verifies a signature — opt-in, off by default independently of TLS. Don't put an unconfigured cluster on the public internet, and don't store data you can't recreate.
AGPL-3.0, and what it asks of you.
Your application talks to AnimusDB over the DynamoDB HTTP API using AWS's own SDKs. It links nothing of ours, and using a database over a network protocol does not put your application under that database's licence.
Run an unmodified build, however commercially, and you owe no one any source. The obligations begin when you modify AnimusDB and let people interact with your modified version over a network — that is section 13, and it is the clause that makes this AGPL rather than GPL.
There is no commercial licence on offer today. The contributor agreement keeps one possible, which is a different thing from promising one.
Scenario by scenario, including the clause your counsel will ask aboutFour reference pages sit under this one.
Each section above stops at the point where detail starts being useful only to someone who has decided to look. That detail is here.
Architecture
The two planes and why the split matters, tablets and placement, the consistency model, four deployment shapes with their commands, the six ports, determinism internals, day-two operations, and the known limits in one list.
Compatibility
Every DynamoDB operation with its status and per-operation notes, the data model, and the four differences that will actually show up in your code rather than in a table.
Performance
The cost model operation by operation, what scales with the cluster and what doesn't, six questions worth more than someone else's benchmark, and the benchmark methodology and load generator — with no published numbers yet.
Licensing
AGPL-3.0 scenario by scenario, the section 13 question your counsel will ask, why this licence and not a permissive one, and exactly where a commercial licence stands today.
Longer arguments
And three pieces that don't fit on a product page.
Why lock-in compounds
Lock-in as an options problem rather than a price problem — and an explicit concession that this is not an argument against AWS.
What self-hosting actually costs
The day-two bill written out in full, including the lines that show up in month seven, and the cases where self-hosting is the wrong answer.
Determinism, and why you should care
Simulation testing as risk reduction, with its boundaries drawn, and six questions to interrogate anyone who claims it — us included.