Build Your Own PostgreSQL
What a database is really promising
What You Will Learn
- Separate a database guarantee from the mechanism that implements it
- Explain durability, consistency, and queryability as contracts under pressure
- Trace how cooperating layers turn a client request into trustworthy state and results
The promise appears when the easy answer fails
A bookstore checkout records an order and receives success. At that moment the power fails. Meanwhile, two inventory workers try to sell the last copy of the same title, and an analyst asks a question that nobody anticipated when the order was stored. A database is valuable because these awkward moments do not cancel its obligations. Accepted facts must survive, concurrent changes must produce a coherent outcome, and stored facts must remain open to new questions.
When nothing fails and only one request runs at a time, a file can look surprisingly database-like. Append a line for each order, scan the lines for a report, and rewrite the file when inventory changes. The weakness is not that files cannot hold bytes. It is that the design has not said what success means when writes overlap, stop halfway, or must be interpreted years later.
Start with contracts, not components
A guarantee describes what the caller may rely on. A mechanism describes how the server earns that guarantee. Confusing the two creates fragile designs. Saying "we wrote a file" names a mechanism; it does not establish that an acknowledged order survives a crash. Saying "we use locks" names another mechanism; it does not establish which concurrent outcomes are allowed. The contract comes first because it supplies the test that every mechanism must pass.
PostgreSQL exposes many features, but three broad contracts organize the machine. Durability says acknowledged changes remain recoverable. Consistency says database rules and internal structures continue to agree. Queryability says callers describe a result rather than a storage route. None of these is delivered by one component. Each emerges from a chain of smaller, checkable responsibilities.
Three contracts, three kinds of pressure
Durability is tested by interruption. The server may change memory before it changes final data files, so commit cannot merely mean "the newest page was written." PostgreSQL records enough ordered evidence to reconstruct committed work. Later lessons will examine that evidence; for now, the invariant is simpler: a successful reply must not depend on volatile state remaining alive.
Consistency is tested by competing interpretations. Column types, constraints, transaction boundaries, indexes, and metadata must describe one compatible world. Consistency does not mean that every reader always sees the newest possible value. It means the server follows declared rules for which state is valid and which version a particular operation may observe.
Queryability is tested by novelty. SQL states the relation a caller wants, not the loop or file offsets used to produce it. That separation lets PostgreSQL change access paths as data, indexes, and statistics change. A declarative query is therefore another contract: preserve the requested meaning while remaining free to choose the route.
Map of the machine
Read the map as a chain of evidence
Follow one order lookup. The client first becomes an identified stream of requests. Text is then given syntactic shape and bound to real database objects. The planner chooses a legal route, and the executor asks storage for rows. If work changes durable state, the storage and log layers preserve enough ordering for recovery. The result travels back only after the relevant contract has been satisfied.
Each arrow is a handoff with an invariant. Parsing must not silently change the statement. Binding must not attach a name to the wrong object. Planning may change the route but not the result. Execution must respect the chosen transaction view. Storage must not let a data page reach durable storage ahead of required log evidence. The architecture is understandable because responsibility changes at explicit boundaries.
Why not let one function do everything?
For a tiny database, one function can accept SQL, scan a file, and return rows. It may even be the right starting point. The trouble arrives when every new guarantee becomes another special case inside the same control flow. Crash handling must understand query execution, query optimization must understand byte layout, and authentication must understand storage. Local reasoning disappears because every concern can affect every other concern.
Layers do add work. A small lookup passes through several representations before touching a row. That cost earns modular reasoning: the planner can compare paths without knowing network messages, while recovery can restore pages without parsing SQL. The point is not to maximize the number of boxes. It is to place each invariant where one subsystem can defend it.
The contract is stronger than the happy path
A useful database design can answer three questions precisely. What does a success reply permit the caller to forget? Which intermediate states may exist internally but never become observable as committed truth? Which implementation choices may change without changing a query's meaning? If those answers are vague, adding more mechanisms only hides the uncertainty.
The recurring method in this track will be to begin with a contract, find the pressure that breaks the simple implementation, and introduce the smallest mechanism that restores the invariant. PostgreSQL is a large system, but its guarantees are built from modest rules composed carefully.
Three questions for every promise
When evaluating a database guarantee, ask three things. What event lets the server report success? Which failures must the promise survive after that event? Which lower-level evidence lets restart or a concurrent observer verify the claim? Precise answers turn broad words such as durability and consistency into testable contracts. Vague answers usually conceal an assumption about memory, timing, or a single client that production will eventually violate. That is the design standard.
Into the server body
Before SQL can be interpreted or durable state can change, client work needs somewhere to run. The next lesson opens the server and asks how many independent workers can present one database without confusing private work, shared coordination, and lasting state.