Document Store

Holds documents instead of rows. No joins and no connections to pool: one flat rate of reads and writes, and each query needs its own index.

The Document Store holds documents instead of rows, as MongoDB, Firestore and DynamoDB do.

When to place it#

  • Place it when the schema keeps changing and features ship slowly because of it. A Feature that changes the data shape is the reason to own one, and the Team backlog shows it: its Dev Hours drop the moment the Store serves.

  • Place it when the work is documents read and written by key: a profile, a cart, a settings page. It unlocks with Document databases in Series A, for 3,500 ◇.

  • Skip it for reports. A report works, but badly, so link a Data Warehouse instead, or leave reports on the Database, which still holds the money.

  • Keep the money on the Database and the documents here.

How it works#

It trades joins and transactions for developer velocity, and it is the mirror image of the Database: cheaper to change, worse at questions that span more than one record.

It serves q-read and q-write on documents, answers a checkout's q-tx and a report's q-scan too, and sends nothing on. It has one flat rate of 3,000 ops a second at its first size, doubled at each of its eight sizes. A read or a write is one op. A join is three. Past its rate the excess is dropped, like any flat-capacity Node.

It differs from a relational table in three ways:

  • No joins. A query that spans several documents is a scan of the collection, at three times the ops. A checkout that writes several documents is not atomic unless multi-document transactions are on, and with them every write waits for the rest, so its latency rises by half.

  • No connections to pool. An App Server opens no pool it has to share through a Connection Pooler, so a spike of App Servers cannot exhaust it the way PostgreSQL's 100 connections are exhausted. It has no buffer cache and no IOPS volume either, so no disk limit applies.

  • No schema to migrate. A Feature that changes the data shape costs 25% fewer Dev Hours, because there is no migration to write, run, or lock a table for. Every other Feature costs 10% more, because with no joins each access pattern it adds is its own collection and index to write and read. The Team panel charges the total.

A join costs three ops#

A Feature that adds reads suits a Document Store, which answers them at one op each from its own flat rate. It cannot cheaply ask two documents about each other:

What it answersOps it costsWhy
A read of one document1A key lookup, or an index lookup on one collection.
A write of one document1One document is atomic.
A checkout (q-tx)3It reads the cart, writes the order and writes the receipt, in the app.
A report (q-scan)3It scans the whole collection, because there is no join to narrow it.

A hot shard from incident Hot key divides its rate, the same way it divides a Wide-column Store's.

Options#

  • Multi-document transactions: they make a checkout atomic across documents, and every write waits for the rest, so its latency rises by half.

How it fails#

  • The join. A checkout spread over documents loses atomicity without multi-document transactions: a retry can charge the card twice, and the card shows the duplicate. Turn them on, and pay half again the write latency.

  • The report. A q-scan through a Document Store is a collection scan at three ops. It also holds the Collection's slots while it runs.

  • Hot keys. One shard's key takes the traffic, and the Node's flat rate is the first thing that bends.

  • A Document Store is not a Database. Nothing joins, nothing is transactional by default, and there is no point-in-time recovery to research. A Design that keeps its money here loses a charge now and then.

Instance failure#

  • Signs: The Document Store card goes grey and its callout reads "The host under this VM died. It still bills." Requests sent to it are stranded.

  • Do now: Select the Node and click Replace. It costs Cash and comes back cold.

  • Prevent: Run a second Node of the Component, so one is still serving while the other is replaced.

Zone outage#

  • Signs: Every Node in one zone goes grey at once, the Document Store with them.

  • Do now: Nothing brings the zone back sooner. Fail over promotes a Standby, and this Component keeps none, so it ends on its own after at most 120 s.

  • Prevent: Research Multiple zones and keep a copy of the Component in a second zone.

Region outage#

  • Signs: One region's board goes grey and the Document Store in it goes down.

  • Do now: Nothing speeds it up. Fail over moves only Nodes that hold no data, so this one stays down until the incident ends: 180 sim seconds in the catalog, 60 once the error budget counts. A store spread across regions needs nothing from you.

  • Prevent: Research Multiple regions, keep a copy in a second region, and add GeoDNS to send users there.

Operator typo#

  • Signs: Every Document Store Node in one region goes down at once.

  • Do now: Place a new Document Store in that region and link it. The incident ends once one Node of that Component is up again.

  • Prevent: Research Infrastructure as code, so a plan shows what a change removes before it runs.

Tips#

  • Link the App Server to both the Database and the Document Store, and each takes the kinds it accepts.

  • Put a Cache in front. Its hits never reach the Store at all, and the Store has no buffer cache, so its reads do not compete with one.

Rules#

  • Each further copy costs 25% more than the one before.
  • Selling it refunds 50% of what its last copy cost.
  • It has 8 sizes. Each step doubles its capacity and its Burn.
  • A new copy starts cold and is slow until it warms up.

Works with#

Database, Connection Pooler, Cache, Data Warehouse, Wide-column Store

Engineering terms#