Skip to content
Muhammet Şafak
tr
Updated 3 min read

Is PostgreSQL Enough for Everything?

Before adding a separate search engine, queue, or document DB: how far PostgreSQL gets you on its own, and where its limit begins.

TL;DR

Most of the list that puts Elasticsearch, MongoDB and RabbitMQ next to PostgreSQL is carried by a single PostgreSQL for a long time: tsvector with a GIN index for search, jsonb for documents, SELECT FOR UPDATE SKIP LOCKED for a moderate-volume queue. The limits are honest and real, but a second data system should arrive on a measured limit, not on a hunch or a blog post.

Is PostgreSQL Enough for Everything? — cover image

An architecture plan, drawn up before there was a single user, carried this list: PostgreSQL for durable data, Elasticsearch for search, Redis for cache, MongoDB for flexible documents, RabbitMQ for queueing. Five separate data systems — each with its own backups, monitoring, version upgrades, and distinct failure mode.

Most of that list, for a long time, a single PostgreSQL carries on its own. The question isn’t “can PostgreSQL do this”; it’s “did you really buy the operational burden of these five systems”.

PostgreSQL’s little-known breadth

Treating PostgreSQL as just a table-row store uses a small fraction of what it can do. Most of the needs that prompt a separate system are already inside it:

  • Full-text search. A real search built on tsvector, tsquery, and a GIN index. It covers most apps’ “search products” and “search posts” needs, including stemming, weighting, and ranking.
  • Document storage. A jsonb column, paired with a GIN index, is a queryable document store. You can keep the fields that want schema flexibility right inside the relational table.
  • Queues. SELECT ... FOR UPDATE SKIP LOCKED and LISTEN/NOTIFY run a moderate-volume job queue without a separate broker. Laravel’s database queue driver uses the SKIP LOCKED half of it — its workers poll the jobs table at intervals rather than waiting on a LISTEN/NOTIFY signal.
  • Analytical queries. Window functions, CTEs, materialized views — serious reporting without reaching for a separate analytical database.
  • Geospatial data. Location queries via the PostGIS extension.

These features aren’t “present but unused”; they’re mature capabilities that run reliably in production.

The quiet payoff of a single system

Every new data system isn’t just a box; it’s a maintenance commitment. What you gain by staying on one system:

  • One backup line. One backup/restore procedure, one recovery drill.
  • One monitoring target. One set of metrics to learn, one alerting setup to build.
  • Cross-consistency. This is the most important one. If your search index lives in the same database as your data, there can be no drift between them — both update in the same transaction. A separate Elasticsearch will eventually fall out of sync with the data, and fixing that becomes its own line item.
  • One mental model. The team learns the quirks of one system, not five.

This is the data-layer version of the innovation-token logic from the boring architecture piece: every new system is a token, and tokens are limited.

Where does the limit begin?

PostgreSQL isn’t enough for everything — it has honest limits, and ignoring them is also a mistake:

  • Search. When typo tolerance, advanced relevance tuning, faceted search, and multilingual analysis are needed at serious scale, a dedicated search engine genuinely pays off.
  • Queues. When you need very high throughput, complex routing, or multi-consumer fan-out, a real message broker is the right tool. A PostgreSQL queue is comfortable at moderate volume, not at the extremes.
  • Write throughput. Sustained writes beyond a single primary’s fsync capacity — this is the hardest breaking point in data-intensive systems, and a real limit.

When you hit one of these limits, bringing in an extra system is the right call. Bringing it in before you hit it is just a guess.

The decision: PostgreSQL first, then measure

The rule is plain: in a new project, make PostgreSQL do everything PostgreSQL can do. Let it be the first stop for search, queue, and cache-like needs. A separate system should arrive only when a measured limit is crossed — not from a hunch, a blog post, or résumé anxiety.

Most teams use maybe 20% of PostgreSQL, then say “it’s not enough”. What’s not enough is usually not PostgreSQL, but the effort to get to know it.


PostgreSQL isn’t enough for everything — but it’s enough for far more than you think. Before you bring in a second data system, ask whether you’ve truly reached the end of the first.

PostgreSQL first; let the rest follow from measurement.

Frequently asked

2 questions

  • Can PostgreSQL replace a separate search engine?

    For most applications, yes. tsvector, tsquery and a GIN index give a real full-text search with stemming, weighting and ranking. A dedicated engine starts paying off when typo tolerance, advanced relevance tuning, faceted search and multilingual analysis are needed at serious scale.

  • Can PostgreSQL be used as a job queue?

    At moderate volume, yes. SELECT ... FOR UPDATE SKIP LOCKED lets several consumers pull work from a queue-like table without lock contention, and LISTEN/NOTIFY signals that the table changed. Very high throughput, complex routing or multi-consumer fan-out is where a real message broker is the right tool.

Sources

In practice

Posts and answers where this principle was applied:

Related

Comments

Sign in with your GitHub account to join the discussion. Comments are stored in GitHub Discussions.

Search the site

Start typing to search posts, projects and pages.

Esc to close Powered by Pagefind