Skip to main content
Engineering7 min read

PostgreSQL Is the Only Database You Need (Until It Isn't)

Postgres handles 90% of SaaS workloads. JSONB, full-text, pgvector, queues. Here's when it's enough, and the four cases where we reach for something else.

One Database Should Be Your Default

Most SaaS startups overthink their data layer.

The pitch deck has Postgres for transactional data, MongoDB for documents, Elasticsearch for search, Redis for caching, and a vector database “for the AI features.” Five systems, five sets of credentials, five backup strategies, five places things can go wrong at 3 AM.

We’ve inherited that stack from clients more than once. We’ve also rewritten it onto Postgres alone, and watched response times drop and ops costs fall.

One client came to us with a B2B analytics product running Postgres + MongoDB + Elasticsearch + Redis. Four databases, three engineers spending most of their time on data sync between them.

We migrated everything to a single Postgres 18 instance with JSONB, tsvector, and pgvector over six weeks. Their monthly database bill dropped from $4,200 to $380. Their on-call rotation got quiet.

The honest 2026 answer: PostgreSQL handles roughly 90% of what a B2B SaaS needs. The other 10% is real, but it’s narrower than the consultants will tell you.

Postgres has been the most-used database in the Stack Overflow Developer Survey every year since 2023. In the 2025 survey it pulled to 55.6% among professional developers, a 15-point lead over MySQL. The “boring” choice is also the popular choice.

This post is about both halves.

What Postgres Quietly Does That People Forget

Postgres started as a relational database. It still is one. But the engine sitting in your docker-compose.yml does considerably more than SELECT * FROM users.

Documents, with constraints

JSONB has been production-ready since Postgres 9.4 (2014). You get document storage with schema flexibility, GIN indexes for fast lookups inside the JSON tree, and the ability to drop down to relational columns when a field stabilizes.

We’ve had clients who picked MongoDB “because we don’t know our schema yet,” then spent eighteen months building joins by hand in application code. The same data in Postgres + JSONB would have shipped faster and stayed queryable with SQL.

Full-text search that’s good enough

tsvector and tsquery have been in Postgres since 8.3. With GIN indexes and ts_rank, you get search that holds its own against Elasticsearch for most B2B use cases. Multi-language stemming, prefix matching, ranked results, all in your existing database.

Is it as flexible as Elasticsearch for log analytics or massive document collections? No. For “let users search their own records,” it’s plenty.

Vector search, since pgvector

The arrival of pgvector, and the maturity of HNSW indexing in pgvector 0.8 (iterative scans, faster builds, better filtered-query performance), changed the AI conversation. You don’t need Pinecone or Weaviate for most RAG applications. You need a Postgres extension and a query.

We’ve built RAG systems for clients where the entire vector store is a single embeddings table next to their existing data. Joining vector similarity against tenant filters, permission checks, and recency rules in one SQL query is genuinely magical when you’re used to syncing two databases.

Queues without Redis

Skip Redis. SELECT FOR UPDATE SKIP LOCKED (Postgres 9.5+) gave us a primitive that’s good enough for most job queues. Solid Queue (Rails 8) processes 20 million jobs per day at HEY on top of it. River for Go, Procrastinate or PgQueuer for Python, Graphile Worker for Node.

For most teams, “I don’t need Redis” is one fewer system to monitor, secure, and pay for.

Real-time, kind of

LISTEN and NOTIFY give you pub/sub inside Postgres. Logical replication streams row-level changes to anywhere you want them. Combined with WebSockets in your application server, that’s enough for most “show me when this record updates” features.

Not enough for chat-app-scale fan-out. Plenty for the live dashboards and notifications a B2B SaaS actually ships.

Why the Single-Database Default Wins

Operational simplicity is undervalued, especially in companies with no dedicated platform team. Most B2B SaaS companies don’t need Kubernetes, service meshes, or polyglot persistence. They need to ship features and not get paged on weekends.

One database means one connection pool, one backup strategy, one set of access controls, one set of metrics to monitor, one upgrade path. Your psql skill works on every part of the system.

Multi-tenancy decisions get simpler too. Whether you go shared schema with row-level security or schema-per-tenant, Postgres handles both natively. We covered the trade-offs in data isolation and security in multi-tenant systems.

A single Postgres instance on a Hetzner server with proper indexing, connection pooling via PgBouncer, and a managed read replica handles tens of thousands of requests per second. Most B2B SaaS never hits that ceiling.

If yours does, congratulations. You can afford a platform engineer.

When Postgres Stops Being Enough

Postgres is the right starting point. It’s not the right finishing point for everything.

Time-series at scale

Once you’re ingesting hundreds of thousands of rows per second of metrics, IoT readings, or financial ticks, vanilla Postgres starts to hurt. Indexes balloon, vacuums lag, and partitioning becomes a full-time job.

TimescaleDB (a Postgres extension) buys you another order of magnitude before you have to leave the family. Beyond that: ClickHouse, InfluxDB, or QuestDB. Choose based on your query patterns.

If you’re below “tens of thousands of inserts per second sustained,” Postgres with pg_partman is genuinely fine.

Search across heterogeneous, massive document corpora

Postgres full-text search is great for “let our users search their own data.” It’s not the right tool when the search itself is the product (think log analytics platforms, public document indexes, or multi-tenant search-as-a-service).

Elasticsearch and OpenSearch exist because that workload is different. Faceting, aggregation across billions of documents, synonym dictionaries, custom relevance models. Postgres won’t beat them at their own game.

True graph workloads

If you’re traversing arbitrary-depth relationships (recommendations, fraud rings, knowledge graphs with deep transitive queries), recursive CTEs in Postgres work but get slow.

Neo4j or Memgraph exist for a reason. The break-even point is later than people think, but it does exist.

Cache that has to live in microseconds

For application-level caching, Postgres + the Solid Cache pattern is fine. For sub-millisecond cache hits at extreme volume (think hot leaderboards, session tokens at 100k req/s), Redis or KeyDB still win.

Most B2B SaaS doesn’t hit this threshold. If yours does, you’ll know.

What We Ship

Default: Postgres 18 on a single managed instance (Hetzner, Supabase, Neon, or AWS RDS) with PgBouncer for pooling and a daily logical backup to an EU bucket. Tenant isolation via row-level security or schema-per-tenant, depending on the product. PG18’s async I/O subsystem and uuidv7 primary keys are the kind of upgrade you get for free by staying on the boring path.

JSONB for anything genuinely document-shaped. tsvector for in-app search. pgvector for retrieval-augmented features. SELECT FOR UPDATE SKIP LOCKED (or Solid Queue, River, Graphile) for background jobs.

When clients hit a real ceiling, we add specifically what they need. TimescaleDB if metrics ingestion grows past comfort, Elasticsearch as a secondary index if search becomes the product itself, Redis last and only when cache latency shows up in user-facing metrics.

We almost never start with five databases. We almost always end with one or two.

The architectural lesson is the same one we wrote about in our tech stack decision framework: build for the problem you actually have, not the one your pitch deck imagines you’ll have at series B.

Postgres bought you a year, often three. Spend the time shipping product instead of stitching together five systems that all do roughly the same thing.

The rewrite from “five databases to one” is a story we keep telling because we keep watching it work.


Choosing your data layer for a new SaaS, or untangling a polyglot mess that’s slowing you down? Let’s talk it through. We’ll look at your real workload and tell you honestly when you can stay on one database and when you can’t.

Share this article
architectureSaaScustom softwareCTOstartup

Related Articles

Engineering8 min read

Why We Still Choose Rails for B2B SaaS in 2026

Rails powers Shopify's $14.6B Black Friday. Here's why we keep choosing it for B2B SaaS, what Rails 8 changes, and when we'd pick something else.

Updated

Need help building this?

We turn complex technical challenges into production-ready solutions. Let's talk about your project.