PostgreSQL Deep Dive
Welcome
Your application talks to Postgres all day, and nearly everything the server does with those statements happens where you cannot see it. This book is about that side of the connection: how PostgreSQL physically stores a row, why an UPDATE never overwrites one, what the planner is really doing when it ignores your index, and what it takes to run the thing in production — configuration, WAL and point-in-time recovery, replication, partitioning, roles, upgrades. One system, Cartwheel, carries every example from the first page to the last.
About This Course
A row in Postgres is a version, not a slot. An UPDATE does not edit the row you are updating; it writes a brand-new version of it, marks the old one as expired at the current transaction id, and leaves that old version sitting on the page for every transaction that started earlier. One decision, and almost the whole engine falls out of it: snapshots and isolation levels, dead tuples and vacuum, why indexes must be maintained on updates that changed no indexed column, why disk usage grows while row counts do not, why replication ships a physical change log. This book states that idea on page one and then keeps cashing it in.
The second thing it returns to constantly is the cost model. The planner does not follow rules. It prices plans: estimated rows multiplied by per-page and per-tuple cost constants, and the cheapest one wins. So a "wrong plan" is almost always a wrong estimate rather than a stubborn planner, and the repair is to fix what the planner believes rather than to switch off the node it chose. By Chapter 9 you read a plan the way you would read an argument: which number was wrong, where it came from, and what the statistics would have to say for the plan to change.
Every example comes from one running system. Cartwheel is an online grocery-delivery service on a single Postgres box: eight tables, 40 million orders, 4 million delivery events a day, and a Saturday-morning peak of 3,000 orders a minute. Nadia owns that database for all fourteen chapters, as a developer in the first half and as the person carrying the pager in the second. Two failures open in Chapter 1 and are left deliberately unexplained: on the first Saturday of the month checkout goes from 40 ms to 6 seconds, and one morning two customers were both sold the last box of strawberries. The strawberries are settled in Chapter 6 and the Saturday in Chapter 9, each by the machinery the book has built by then rather than by a guess that happened to work.
Who This Is For
Engineers whose product runs on Postgres and who now need the engine underneath it. The bar is deliberately concrete: you can read a SELECT with a JOIN in it, and you are comfortable on a Linux shell, because everything here is driven from psql against self-managed Postgres on Debian. If most of your SQL is generated by an ORM rather than typed by you, the book is more use to you rather than less — dead tuples, lock queues and plan flips do not ask who wrote the statement, and the query the framework built is the one you will be reading in EXPLAIN. No internals knowledge is assumed: page layout, MVCC, vacuum, indexes and the planner are all built from zero.
It is not a first database course. If a JOIN is not yet something you can read, or if "primary key" is a term you would have to look up, read Databases for Beginners in this catalogue first and come back; that book covers tables, relationships and SQL with no engine named and nothing installed, which is exactly the ground this one refuses to re-cover. It is also not a survey of database engines: MySQL, Oracle, SQL Server and the distributed systems that speak the Postgres wire protocol appear only where the contrast explains why Postgres chose differently.
What You Should Already Know
- Working SQL —
SELECT,JOIN,GROUP BY, and what a transaction is for - A Linux shell — editing a config file, reading a log, running a command against a server you can break
- What an index is for; the book starts at what a B-tree entry physically costs on every update
- Nothing about Postgres internals — storage, MVCC, vacuum, the planner and WAL are built from the ground up
How the Course Is Built
The fourteen chapters run in three movements. The developer half (Chapters 1–4) is what an application engineer must know to use Postgres well: the process model and the catalogue, a type system where the column type is a contract rather than a label, constraints and migrations that ship without taking the site down, and the SQL that replaces three round trips with one query. The internals half (Chapters 5–9) is the core of the book: the 8 KB page opened up, MVCC and isolation, vacuum and bloat and freezing, the index types and what each one costs, and the planner. The operations half (Chapters 10–14) is running it for real: configuration and pooling, partitioning a 1.2-billion-row table, WAL and point-in-time recovery, replication and failover, roles and row-level security, upgrades, and a last honest look at managed Postgres.
The version canon is PostgreSQL 18, and a version number appears only where the version is the lesson — a default that changed, a feature that landed, behaviour you will hit on 17 and earlier. Every topic has the same shape: an opening that says what the thing is and why it exists, the mechanics with real psql sessions and real plans, the specific mistakes that cause real outages, the practices that prevent them, and a short knowledge check. Every mechanism gets a number, because the numbers are the difference between predicting Postgres and guessing at it.
Chapter Map
Disclaimer
This course is an independent educational project created and maintained by Sergey Okinchuk. It is provided for learning and reference purposes only.
No affiliation. This course is not affiliated with, sponsored by, endorsed by, or officially connected to any company, product, or project mentioned — including the PostgreSQL Global Development Group, the PostgreSQL Community Association of Canada, EDB, Amazon Web Services, Google, Microsoft, Oracle, Supabase, or Neon. All opinions, interpretations, and recommendations expressed are those of the author.
Trademarks. Product and project names referenced — including "PostgreSQL", "Postgres", "MySQL", "Oracle", "SQL Server", "Amazon RDS", "Cloud SQL", "PgBouncer", "Patroni", "TimescaleDB", and "PostGIS" — are the property of their respective owners. Use of these names is for identification and educational purposes only and does not imply any endorsement.
Not operational advice. This material teaches how PostgreSQL works and the practices that follow from it, not turnkey instructions for any specific environment. Configuration values, snippets, and recovery procedures are simplified for learning and sized for one fictional workload. Always consult the official documentation and test on a system you can afford to lose before changing a production database.
Accuracy and currency. PostgreSQL ships a major release every year and changes defaults with it. Facts in this course are written against PostgreSQL 18 and reflect the author's understanding at the time of writing; version-dependent behaviour drifts. Always verify against the official documentation for the version you actually run.
No warranty. This material is provided "as is" without warranty of any kind. The author accepts no liability for any loss or damage arising from reliance on the content.