Relational model: tables, keys, constraints, when to bend the rules
Why Codd's 1970 relational model still wins on data integrity, what each normal form actually buys, where surrogate vs natural keys diverge, when JSONB and arrays beat a side table, and why some hyperscale shops disable foreign keys.
Indexes in PostgreSQL: B-tree, GIN, GiST, BRIN, and the cost of a wrong one
How Postgres indexes are built (B-tree, GIN, GiST, BRIN, SP-GiST, hash), why the leading-column rule is the most violated principle in production, how partial / expression / covering indexes change the cost model, and when to add or drop one.
Execution plans: how PostgreSQL finds and executes your query
How the PostgreSQL planner reads statistics to pick scans and joins, why row-estimate errors cascade into bad plan choices, and how to lock in a stable plan under traffic.
Connection pooling in PostgreSQL: PgBouncer modes, sizing math, and pool-exhaustion failure modes
Why Postgres backends are heavyweight, how PgBouncer's session/transaction/statement modes change app contracts, the math behind pool sizing, the prepared-statement transaction-mode trap (and PgBouncer 1.21+ fix), and the Supavisor/Odyssey/PgCat landscape.
Schema migrations in PostgreSQL: locks, expand-contract, and the lock-queue failure mode
Why ALTER TABLE behind a long-running query freezes the database, how to decompose every breaking change into safe expand-contract phases, and what nine migration failure modes look like in production.
Sharding PostgreSQL: shard keys, hot-shard failure mode, partitioning vs Citus
When one Postgres is not enough — shard-key selection, hash/range/list/directory strategies, declarative partitioning vs Citus, co-location, the hot-shard failure mode, online resharding, schema-based sharding.
One product grows from a 1-table MVP to a 1-billion-row Citus cluster through seven moments of database failure — schema, indexes, statistics, bloat, pooling, migrations, sharding — each one named, ordered, and triage-ready.