Skip to content

EelgrassThe last database you will need

Eelgrass goes as wide as it goes deep. Ten thousand customers with a megabyte each, or one with a terabyte, on the same engine, keeping every version of everything. It grows with your company instead of being replaced by it.

As wide as it is deep ​

Every other database makes you pick. Postgres goes deep and turns ugly the day every customer needs their own. The edge databases go wide and stop each one at ten gigabytes. The warehouses go deep on reading and give up on writing.

We are building the one that refuses to choose. A database here is a node in a tree: your account holds databases, a database holds a tenant for every customer you have, and any node can be the big one.

Going wide costs almost nothing, because a database nobody is using costs about what one row costs. Going deep does not change the shape, because the machine is a cache and the data lives in object storage.

So there is no migration waiting for you in year three. The database you launch on is the one you are still running when you have a thousand customers and a decade of history.

Numbers from the cloud ​

A customer with 28 gigabytes of data, on the smallest instance Amazon sells.

Memory the machine serving it needs35 MB
Copy that whole customer100 ms
Throw the copy away again49 ms
Read twenty thousand rows1.1 seconds
Load the 28 gigabytes in41 MB a second

The machine holds 35 megabytes of a 28 gigabyte database, because the data lives in object storage and the machine is only a cache. That is also why copying a customer does not get slower as they grow: the same copy took longer at 1.35 gigabytes than it does at 28.

What this replaces ​

The middle column is what you write. The right-hand column is what your team is doing instead, right now.

Six things your team stops building ​

What you need to doHereEverywhere else
Undo six hours of bad writes, and nothing elseorders |> filter batch == b |> revert to now() - 6hRestore last night's backup and lose every order taken since. Or build an undo by hand and hope it was right.
Ask what a record said at any momentorders |> asof "2026-09-01T09:00" |> filter id == oidA point-in-time restore onto a second machine, or an audit-table project, per table, forever.
Copy a customer to test againstfork tenant "acme" as "acme-staging"Export, scrub, restore. Slow enough that people stop bothering and test against made-up data.
Delete one customer, completelydelete tenant "acme"A delete per table, in the right order, and a promise that nobody missed one.
Change two customers with a checked undoflow { step ... compensate ... }A saga framework, or a distributed transaction nobody trusts.
Hand a customer their data and leaveeelgrass export ./crm acme acme.eelpkgA ticket, a script, and a week.

Two things you stop buying ​

What you need to doHereEverywhere else
Get every change, with the fields that changedGET /t/acme/tail?after=412Logical replication, a change-capture service, a topic, and a consumer that puts the row back together.
Report across customers without a warehouserollup Daily { across tenants (name == "acme/*") ... }A copy of the database, a warehouse, a pipeline between them, and two teams to change one number.

The second table arrives with invoices, so somebody notices it. The first arrives with salaries, and it lands on the people you can least afford to have doing it.

You are not buying a faster database. You are deleting the right-hand column.

See every line of the middle column run properly

Want to look properly? ​

We are building with a small number of companies who have these problems and want a say in what gets built.

Talk to us

A database that remembers, so mistakes are fixable and every customer's data stays separate.