Learn System Design Choosing a database

Backend

How to choose a database: seven laws

Nobody picks the wrong database on purpose. They pick it in the wrong order: engine first, queries later. These seven laws run the decision the other way round, and each one is really just a question you have to answer out loud.

7 laws 5 scaling lenses ~6 min
Infographic of the 7 database laws for how to choose a database: start with queries, consistency by business rules, find bottlenecks first, understand workload scaling, use one database until you have a specialized need, speed is not durability, and think ops and failure, not just dev.

The seven laws at a glance. Save it, or keep scrolling for the walkthrough.

The choice is rarely about features

Ask how to choose a database and you will get a comparison table. Rows for transactions, documents, horizontal scaling, and a tick in most of the boxes for most of the options. The table is accurate and it will not help you, because the databases people regret were almost never missing a feature. They were fine at the thing the team measured and awkward at the thing the team did every day.

That is what these laws are aimed at. Every one of them replaces a product decision with a question about your own system, and the questions are ordered. What you read and write comes before what rules must hold, which comes before where the time is going, which comes before what "scale" means in your sentence. Answer them in that order and the shortlist writes itself.

The central lesson is unglamorous: the goal is not the database with the most capabilities. It is the one that fits the workload, chosen by someone who can describe the consequences of the fit.

Interactive

Walk the chain

Seven links, in order. Pick one to see the law, the question it forces, and the move it saves you from.

Law 1 · 00:00 in the talk

Start with the queries, not the database

What does this application actually read and write?

Most database arguments start in the wrong place, which is the shape of the data. The shape that decides things is the shape of the access. Write down the ten reads and writes the app performs most often, how frequently each one runs, and how much it returns. An e-commerce app whose every page ties customers to orders to products to payments to stock is describing a relational database whether or not anyone says the word. An app that only ever fetches one document by one key is describing something else entirely.

What usually happens

Choosing PostgreSQL, MongoDB or DynamoDB from the data type, the conference talk, or what the last team happened to use.

Do this instead

List your top ten access patterns before you shortlist anything. That list rules out more options than any feature comparison will.

Read as one sentence: Queries → Consistency → Bottleneck → Scaling → Complexity → Durability → Operations.

Law 4, up close

Five things people mean by "scale"

They are five different projects with five different first moves. Pick the pressure you actually have.

How it shows up

Traffic doubled, the same few hundred rows are being fetched over and over, CPU is pinned.

What is really happening

The working set is small and the database is answering the same question repeatedly. This is the friendliest kind of growth.

First moves, in order

Cache the hot answers, then add read replicas and route reporting queries away from the primary.

The expensive mistake

A cache turns a read problem into an invalidation problem, which is a consistency problem. Law 2 decides how stale each cached thing is allowed to be.

Laws 5 and 6, up close

Which of your stores could you lose?

Run every store you operate through one question: if it emptied itself during lunch, where would the data come back from? The honest answers sort your architecture into copies and originals faster than any diagram.

Each store, what it exists for, where it can be rebuilt from, and the blast radius if it disappears
Store Exists for Rebuild it from If it vanishes
Cache Repeat reads of the same hot answers The primary, on demand, as requests arrive A latency spike while it refills. Nothing is lost.
Search index Text search, facets, fuzzy matching A reindex job over the primary Search is down for the length of the reindex. Checkout is not.
Read replica Read capacity and reporting queries Replication from the primary Read capacity, plus anything pinned to that replica.
Analytics warehouse Aggregates across history A replay of the primary and the event log Dashboards go stale. Revenue keeps working.
Queue or event log not derived Work that has been accepted but not finished Only if every producer can re-emit, which is rarer than people assume In-flight jobs disappear silently. This one is usually a store of record wearing a costume.

Watch the last row

Queues get filed under "infrastructure" and treated like caches, but a job that has been accepted and not yet done exists in exactly one place. If the producer cannot re-emit it, the queue is a source of truth, and law 6 applies to it in full: replication, backups, and a restore somebody has rehearsed. This is the row that quietly breaks the pattern in most systems we have looked at.

Test yourself

Four calls a senior makes differently

Each one maps back to a law above. Nothing is saved or sent anywhere.

Question 1 of 4 Score: 0
Checkout has gone from 200ms to 3 seconds since last month. What do you do first? basic

The short version

Start general, specialise on evidence

The senior move is not knowing more databases. It is starting with a general-purpose one that fits what you currently understand, then measuring, optimising, naming the actual bottleneck, and only then adding specialised infrastructure with a reason attached to it. Specialisation bought early is complexity you pay for daily and benefit from hypothetically.

One question belongs in the decision and rarely makes it: how hard would this be to leave? You will not get it perfectly right, which is fine, so long as being wrong is survivable.

Data portability

Rows and documents move. The shape you gave them to satisfy one engine's quirks does not, and that reshaping is most of the migration.

Engine-specific features

Every stored procedure, vendor extension and clever index type is a small rope tying you to the choice. Some are worth it. Count them anyway.

Application coupling

If query building leaks across the codebase instead of living behind a data layer, changing databases means changing everything that touches one.

Keep going

More system design breakdowns, built the same way.