Postgres is eating the stack
Postgres quietly absorbed the queue, the search engine, and the vector index, and the honest case for where to stop is worth more than the hype.
Bob Bass
For most of two decades, the standard architecture of a new product was a kit of parts: a relational database for the tables, a message broker for anything asynchronous, a cache in front of it, a search server for the text, and eventually a vector index for the embeddings. Each part came with its own deployment, dashboard, backup regime, and page at 2am. By the time a product had real users, the team was maintaining a small museum of specialized systems, and a meaningful share of all engineering went into making the exhibits agree with each other.
Sometime in the last few years, a large fraction of new projects quietly stopped building the museum and put the whole collection into Postgres. That is not laziness and it is not fashion: it is the payoff of a decade of steady, unglamorous extension work. The case for consolidating is genuinely strong. The interesting question is where it stops being safe, because it does stop for a few workloads, and knowing that line is what makes the default defensible.
What one surface actually saves
The core job has not moved: for structured records with invariants, Postgres was always the right engine. What changed is everything orbiting it, and the clearest example is the queue. A jobs table using SELECT ... FOR UPDATE SKIP LOCKED, a status column, and a few dozen lines of worker code gives you a durable work queue with retries, backoff, and dead-lettering, and it runs inside the same transaction that mutates the rest of your data. The worker that charges a card and the row that records the charge cannot disagree, because there is no second system with its own opinion about the truth.
The alternative used to cost a broker (RabbitMQ, Kafka, or Redis in one of its queue poses), a serialization format, and a reconciliation script for when the broker and database drift. Pulling it out returns weeks of dual-write code, cross-store consistency checks, and a dependency nobody re-audited after setup.
Full text search tells the same story. tsvector columns, GIN indexes, and websearch-style queries cover documentation search, product catalogs, and ticket lookup, and jsonb with expression indexes covers the document-store workloads that once justified a separate database. pgvector puts embeddings next to the rows that produced them, so a similarity search joins straight onto permissions and filters instead of syncing with an external index twice a day and hoping.
The honest accounting: each specialist tool shipped capabilities Postgres genuinely lacked five to seven years ago, and most of those now live in Postgres at a quality that satisfies everyone except the demanding edge. The operational savings are not marginal either, because backups, point-in-time recovery, access control, and alerting attach to one surface instead of five.
What still belongs to a specialist
The edge is real, and pretending otherwise is how teams end up rearchitecting at the worst possible moment. Three workload families still reward a purpose-built engine, each designed for jobs Postgres deliberately does not chase.
Heavy time-series is the first. Continuous ingestion of machine telemetry (thousands of series, retention windows, rollups on arrival) rewards columnar storage and engines built around append-mostly data, such as ClickHouse or the lineage behind Prometheus and InfluxDB. Partitioning and BRIN indexes carry Postgres further than people expect, but past a certain ingest rate you tune the engine instead of using it.
Planet-scale multi-master is the second. Postgres replication is asynchronous with one writable primary. If the real requirement is writes landing in two continents with serializable guarantees and local read latency, no extension fakes it: that is the territory of systems built around consensus (the Spanner lineage, with CockroachDB as its open descendant). They pay for themselves only when the requirement is real, which is rarer than diagrams suggest, but not negotiable when it is.
Search ranking at scale is the third. Postgres full text search ranks with sensible heuristics, and that is its ceiling. If search is the product (a marketplace where relevance decides conversion, or a platform whose customers tune ranking weekly), you eventually need BM25 controls, synonym strategy, learning-to-rank, and ranking changes shipped against billions of documents on a latency budget. Elasticsearch and OpenSearch exist because relevance engineering is a discipline with a feedback loop, and that loop needs a home.
The honest test for when to split
Start with Postgres and split on evidence, not anticipation, because the first specialist reintroduces the glue problem the consolidation removed. A few signals mark the genuine moment. One is when a secondary capability becomes the product's core promise, the way search relevance does on a marketplace. Another is when one workload's growth damages a different one: analytics queries contending with the transaction path, or a queue table growing until autovacuum is a recurring topic in standup. A third is when you are visibly fighting the engine, with workarounds stacked on workarounds.
When a split happens, do it once and deliberately: move the workload to the engine built for it, keep the master data in Postgres, and write down why while it is fresh. Most products never hit these lines, and for them "just use Postgres" is not a hot take but the settled conclusion of a decade of boring, verifiable work. The teams running four databases again are the ones that earned it by outgrowing one, and knowing where that line sits is what makes the default a default rather than a gamble.
From the desk that wrote this
This blog is run by the team behind Layerbase, so every post comes with a conflict of interest attached rather than concealed behind it.