$ cat choices/postgres.md
the call
Default to Postgres, and keep defaulting to it far longer than you think you can. It's the relational core that also moonlights as your queue, cache, search, and document store: one battle-tested engine instead of five half-understood ones. I reach for something else only when Postgres has genuinely run out of room.
Postgres does the relational job better than almost anything, and then keeps going: a job queue with SKIP LOCKED, a document store with JSONB, full-text search, geospatial, pub/sub with LISTEN/NOTIFY. Every one of those is a system you didn’t have to add, and each system you don’t add is a query language, a backup story, a monitoring setup, and an on-call rotation you don’t have to own. That’s not technical debt, it’s technical credit: you buy simplicity now and it pays dividends every quarter you don’t spend operating a zoo.
When you’ve genuinely outgrown a dimension: firehose write volume, global multi-region low-latency, a specialized workload (massive-scale vector or time-series) that Postgres can serve but not best. The discipline cuts both ways. Don’t bolt on Redis and Kafka and Mongo on day one out of habit, and don’t contort Postgres into something it’s bad at just to avoid a second system once the second system is genuinely earned. The skill is knowing the real edge of the box, not fearing it from across the room.
This is close to a law for me, and by now it’s a whole genre of essays, which is the tell: people keep writing “just use Postgres” because it keeps being right. “Just Use Postgres for Everything,” “It’s 2026, Just Use Postgres,” and the steady drumbeat behind them all make the same case. The honest confession: the one I always wanted to reach for and never got to live was CockroachDB. Postgres-wire-compatible, horizontally scalable, survives a region going dark. The distributed-SQL dream. I never had the problem big enough to justify the move, and that’s exactly the point: you earn Cockroach, you don’t cosplay it. Postgres until it hurts, then the right distributed answer.— see: amazingcto.com · tigerdata · mccue.dev
Prefer one tool you understand deeply, stretched to its real limits, over a fleet of specialized ones you each half-operate. Every new datastore is a fixed operational tax. Pay it only when the workload forces your hand, not when an architecture diagram looks more impressive with five boxes. The teams that drown aren’t the ones that kept it simple too long; they’re the ones that added complexity before they’d earned it.
the gaps — what it costs even when it’s right
The moonlighting has ceilings. Postgres-as-a-queue and Postgres-as-a-cache are great until your throughput says otherwise, and the failure is often subtle: a slow creep of contention rather than a clean wall. Watch for the edge instead of assuming there isn’t one.
One big database is one big blast radius. Consolidation buys simplicity and concentrates risk. That single instance’s tuning, backups, and failover are now load-bearing for everything. Simplicity is not the same as resilience; you still have to engineer the latter.
Scaling writes is the real wall. Reads scale with replicas; the primary’s write ceiling is where “just use Postgres” eventually meets its limit. That’s the moment the distributed-SQL conversation (Cockroach and friends) stops being a dream and becomes the job.