TessariDB
Get started

Why one store

The seam is the cost.

A database, a search engine, a vector index, a cache, a queue, an event log and something holding the files are each good at their own job. What none of them owns is the seam between them — and the seam is where the write that cannot be made atomic lives, along with the reconciliation job, the fusion step, the provenance convention half the pipeline forgets, and a dozen things to upgrade.

The same work, two architectures

No product is named here, on purpose. The comparison that matters is between shapes of system, and it holds whichever ones you picked.

What you are doingA stack and its seamsOne store
A write that touches text, an embedding and a linkThree or four writes, in an order you chose, with no way to make them atomicOne transaction — all of it lands, or none of it does
A failure half way through that writeAn embedding with no text, or a chunk with no vector, found later by a jobThere is no half way through
A read that filters and ranksA query per system, intersected in application codeOne statement; the store resolves the filter and the ordering together
Ground truth for measuring recallA second system, trusted to tell you how wrong the first one isThe same store — exact until the statement says APPROXIMATE
Where an answer came fromA column convention, kept by every writer that remembers toAn edge — a traversal, and data rather than a naming scheme
A cache, a lock and a rate limit beside the dataAnother service, its own failure modes, and a key that outlives the record it describedA space: keys that expire, counters, SET … IF ABSENT — in the same transaction as the record
Events several parts of the application readA broker, plus an offset store, plus the question of what happens between committing one and the otherA topic whose reader's position commits with what the reader writes here — once per message
Words and meaning ranked togetherTwo queries and a fusion step you write, tune and ownORDER BY FUSE — by where each record came in each order, never by adding a score to a distance
Standing it up to trySeveral services, their versions, and the compose file between themOne binary; in memory if you do not even want a directory
Operational surfaceA dozen systems, each with its own backup, upgrade, auth model and failure modesOne process, one backup, one grant model, one upgrade

Not the fastest at any one thing. Enough at all of them.

This is the trade, and it is better said here than discovered. A system built for one job — a search engine, a broker, a cache — will beat a general store at that job, and there is no benchmark on this site claiming otherwise, because none has been measured and published. Most projects never push any one of those jobs to where the difference shows. What they do pay for, every week, is running all of them: the versions, the backups, the auth models, the upgrades, and the reconciliation between them. That cost is the one a single store removes.

It grows with the project rather than being replaced by it. The same binary runs in memory for a test, on a directory for a service, with followers for copies, with automatic failover when a leader is lost, with tables split by key range across machines, and with two writers on one range. Each step is a declaration, not a migration to a different product.

And a project may outgrow one part of it. The data is one log behind a published protocol and five clients, so moving one workload to a specialist is a decision you take when the numbers say so — not a cost you pay on the first day, for a load you may never have. We work to make every engine as good at its own job as it can be; we do not promise it will be enough forever.

Where a single store is the wrong answer

A page that only lists advantages is a page that has not been checked. These are the cases where the argument above does not apply, and saying so is cheaper for both of us than finding out in week three.

  • You need a dataset that reshards itself as it grows. Clustering, replication, failover and sharding by key range are in the released engine, and a split table's shards are split and merged by statement — but nothing splits a table on its own, a split moves no record already written, and the largest shard has to fit one machine.
  • Your embeddings are the whole workload and run to billions of vectors with a dedicated recall and latency budget. A specialist index will beat a general store at its own game.
  • Your existing stack already works and the seam is not costing you anything you can name. Replacing a system that is not hurting is how a quarter disappears.
  • You need a mature ecosystem of connectors — dashboards, CDC sinks, managed hosting. This is a young engine with a published protocol, not a marketplace.

More than one machine

Clustering, replication and sharding.

Distribution shipped in 0.2.0-beta, and this table is the honest state of it. A row marked Today is behaviour you can run right now; one row is still direction, and it is marked as direction so that nothing on this site has to be walked back later. The shapes a deployment can take, and what each one costs, are on their own page rather than repeated here.

Topology as dataToday

DEFINE NODE says what this machine is and where it answers; DEFINE REPLICA says which peers exist. INFO FOR NODE reads both back in one answer. The topology is in the catalog, so it is backed up; the identity is not, so a restored node does not inherit someone else's.

Draining a nodeToday

Taking writable away is how a node is drained, and it stays readable throughout.

Backup and restoreToday

The log is written out and replayed back, with a sequence bound on either end.

Replication of data between peersToday

A namespace declares how many copies the cluster keeps and a peer subscribes to some of them, so replication is per namespace rather than per machine. Switching it on for a namespace that already holds data brings the history across with no repair step.

Failover, quorum, leader electionToday

A leader writes under a lease it renews against a majority and refuses writes before that lease expires, on monotonic elapsed time. Losing one is noticed by a heartbeat on the peer link before the slower awareness round sees it.

Two writers on one rangeToday

A range can be declared multi-master. What that gives up is single-copy semantics, so a write concurrent with the stored version is refused and names both versions and the node that wrote the other one.

ShardingToday

A table declared with SPLIT AT is split by key range. Each shard is logged, led and replicated on its own, and a node holding part of a table answers a read of all of it or refuses.

ReshardingToday

A split table's shards are split, merged and moved to another leader by statement while it serves. A split moves no record already written, a table declared without SPLIT AT cannot be split, and nothing splits a table on its own.

The part that already exists is the part that is easiest to get wrong later: a node’s identity and the cluster’s topology are stored in two different places on purpose. Identity stays local, so a node restored from another node’s backup does not inherit writable and start accepting writes the real writer never sees. Topology travels in the backup, so a cluster rebuilt from one does not come up believing it is alone. Neither failure would announce itself, which is why the split was decided before the replication was written.

The split is the whole of it. A machine restored from another machine’s backup comes up knowing every peer and knowing nothing about itself — so it cannot inherit writable and start accepting writes the real writer never sees, and a cluster rebuilt from one backup does not come up believing it is alone. The dashed band is the honest remainder: what the drawing shows is what runs today.
The two statements, and why they are twotessariql
DEFINE NODE ROLES serving, writable ENDPOINTS 'here:9000';
-- this machine; local, and deliberately not in a backup

DEFINE REPLICA second AT 'there:9001' ROLES serving, writable;
-- the topology; in the catalog, and deliberately in a backup

INFO FOR NODE;
-- both halves, in one answer

Progress is reported in the documentation rather than announced here, so the page describing a capability and the capability itself land together.