PostgreSQL
12 engineering logs on PostgreSQL. Newest first.
- One round trip beats a thousand, and your batch API probably is not batching
Why a 100,000 row insert takes forty minutes instead of twelve seconds, why addBatch does nothing on the wire without a driver flag, and why autocommit turns every row into a durability barrier.
- Your JSONB column became the schemaless disaster you migrated away from
Why a metadata column with no schema accumulates forty shapes in two years, what TOAST does to read cost when you fetch one key from a large document, and how to promote the keys that turned out to be load bearing.
- Foreign keys are not overhead, and the thing you measured was a missing index
Why dropping foreign keys for performance usually removes a cheap index lookup and leaves the expensive sequential scan in place, and what actually replaces the guarantee once it is gone.
- The replica lag you do not measure is the one serving checkout
Why byte lag reads zero on a broken replica, how read-your-writes breaks the moment you add a read replica, and why routing all reads to replicas is a correctness decision rather than a scaling one.
- ADD COLUMN is not always free, and the lock queue is what takes you down
Why a metadata-only migration still took the site offline for forty minutes, how a waiting ALTER blocks every query behind it, and why lock_timeout is the setting that turns a migration into a retry.
- Connection pool sizing is a queueing theory problem, not a tuning knob
Why Little's law gives you the pool size in one line, why raising it past the knee adds latency without adding throughput, and why twenty pods with twenty connections each is a number nobody decided on.
- Soft deletes are a schema decision that breaks every query you write afterwards
Why deleted_at IS NULL leaks into every index, breaks unique constraints in a way that only shows up when a user re-registers, and moves referential integrity out of the database and into whichever service remembers to filter.
- Covering indexes: the cheap 10x that most schemas leave on the table
Why a matching index still costs you one random read per row, how INCLUDE columns turn that into an index-only scan, and why Postgres will quietly keep hitting the heap anyway if the visibility map is stale.
- Why your index is not being used, and why the planner is usually right
The index exists and EXPLAIN still says sequential scan. A field guide to sargability, stale statistics, the leftmost prefix rule, and the cost settings that make a planner reject an index it should have chosen.
- fsync is the only thing between you and data loss, and it is slower than you think
Why a successful write() means nothing, what fsync actually costs in the cloud, and why synchronous_commit off and fsync off are not the same knob despite being discussed as if they were.
- Decoding isolation levels: I built a toy DB to force dirty reads and phantom reads
Why the ANSI isolation table does not describe your database, what a phantom read actually is at the index level, and why snapshot isolation still lets two correct transactions corrupt each other.
- AI agents break connection pooling by holding the slot while they think
Agents keep pooled DB connections open for LLM inference, exhausting pools and evicting buffer cache. Decouple reasoning from data, route agents to replicas, and never hold a connection across an inference call.