DEV Community

Cover image for PostgreSQL vs. MongoDB: A 10x Speedup, a 4-Hour Outage, and the Real Question Behind "SQL vs. NoSQL"
Ciphemic academia
Ciphemic academia

Posted on Originally published at ciphemicacademia.in

PostgreSQL vs. MongoDB: A 10x Speedup, a 4-Hour Outage, and the Real Question Behind "SQL vs. NoSQL"

PostgreSQL vs. MongoDB: A 10x Speedup, a 4-Hour Outage, and the Real Question Behind "SQL vs. NoSQL"

The team behind Shippable, a CI/CD platform running over 50 microservices, rebooted their MongoDB server one day as routine maintenance. It took four hours to come back online. The culprit traced back to index rebuilding, a process that locked the entire database while millions of documents sat untouched by their application. They migrated to PostgreSQL shortly after and never looked back. Years later, the team behind Agenta ran their own migration in the opposite direction of "obvious," moving off MongoDB and onto Postgres, and measured up to 10x faster performance in some of their real workloads.

Neither story means one database is simply better. They mean the same thing every real "SQL vs. NoSQL" decision eventually teaches: the right choice depends entirely on your actual data shape and access patterns, and the wrong choice shows up later as an outage or a performance cliff, not as an error message on day one. This guide compares PostgreSQL and MongoDB honestly, what each one actually optimizes for, where the real numbers come from, and how to decide before your schema assumptions get expensive to undo.

If database fundamentals like indexes, normalization, and query planning are still new to you, our Data Engineer roadmap builds that foundation before this comparison will fully click.

This post originally appeared on the Ciphemic Academia blog.

The Short Version

  • PostgreSQL is a relational database: structured tables, enforced schemas, and powerful SQL for querying across related data, with full ACID transaction guarantees.
  • MongoDB is a document database: flexible, schema-less JSON-like documents, built for fast iteration and data shapes that don't fit neatly into rows and columns.

If you want one default for a new application: start with PostgreSQL. It handles a wider range of use cases well, including many that look "document-shaped," since modern Postgres has strong native JSON support. MongoDB earns its place in specific situations this guide covers below.

What Both Are Actually Trying to Solve

Before the differences, the shared job, since it's easy to lose in the SQL-vs-NoSQL framing:

  • Storing data durably: both need to persist your data reliably and get it back when asked
  • Querying efficiently: both use indexes and query planners to avoid scanning every record for every lookup
  • Scaling with your application: both offer ways to handle more data and more traffic as you grow, just through different mechanisms
  • Maintaining data integrity: both have answers for "what happens if two things try to update the same data at once," though the strength of that answer differs significantly

The actual decision isn't "relational vs. modern." It's a trade-off between enforced structure and flexible structure, and each comes with real, measurable consequences.

One record, two database models: PostgreSQL joins related tables, MongoDB nests one document

PostgreSQL

What it actually is: a relational database management system where data lives in tables with defined columns and types, related tables are linked through foreign keys, and you query across them using SQL. Every row in a table follows the same schema, enforced by the database itself, not by application code remembering to check.

A small example:

CREATE TABLE orders (
  id SERIAL PRIMARY KEY,
  customer_id INT REFERENCES customers(id),
  total NUMERIC(10,2),
  created_at TIMESTAMP DEFAULT now()
);

SELECT orders.id, customers.name, orders.total
FROM orders
JOIN customers ON orders.customer_id = customers.id
WHERE orders.total > 100;
Enter fullscreen mode Exit fullscreen mode

That JOIN is doing real work: combining data from two related tables in a single, efficient query, something a document database handles very differently.

Where it shines:

  • Strong data integrity: foreign keys, constraints, and full ACID transactions mean the database itself prevents a huge class of data corruption bugs, rather than relying on application code to catch them
  • Powerful querying across relationships: joins let you ask complex questions spanning multiple related tables in one query, which gets genuinely painful to replicate in a document model
  • Mature and battle-tested: PostgreSQL has decades of production use, extensive tooling, and a published benchmark found it ran tens of percent to three times faster than MongoDB on equivalent JSON workloads in one FOSDEM PGDay study
  • Native JSON support: modern PostgreSQL's JSONB column type lets you store flexible, document-like data inside a relational database when you genuinely need that flexibility for a specific field, without giving up SQL and transactions for everything else

Where it struggles:

  • Schema changes require more care: adding or changing a column on a huge table can require real planning, migrations, and sometimes downtime windows, compared to MongoDB's inherently flexible documents
  • Horizontal scaling is less automatic: scaling PostgreSQL across many servers (sharding) is possible but historically requires more deliberate setup than MongoDB's built-in sharding
  • Rigid structure can slow early iteration: when your data shape is still genuinely unsettled in an early prototype, defining and migrating schemas repeatedly can feel like friction you don't yet need

Who this suits: applications with clearly related data (orders, customers, inventory), anything where data correctness and consistency genuinely matter, and the sensible default for most new backend projects.

MongoDB

What it actually is: a document database where data is stored as flexible, JSON-like documents (BSON, specifically) inside collections, with no required schema enforced by the database. Different documents in the same collection can have different fields entirely, and nested, complex structures live naturally inside a single document instead of being split across tables.

A small example:

db.orders.insertOne({
  customerId: "c482",
  items: [
    { sku: "A1", qty: 2, price: 24.99 },
    { sku: "B7", qty: 1, price: 79.99 }
  ],
  total: 129.97,
  shippingAddress: { city: "Bhubaneswar", zip: "751007" }
});

db.orders.find({ total: { $gt: 100 } });
Enter fullscreen mode Exit fullscreen mode

Notice the entire order, including nested items and a nested address, lives in one document. There's no join required to read it back as a single unit.

Where it shines:

  • Flexible schema: different documents can have different shapes, which genuinely speeds up early development when your data model is still evolving
  • Natural fit for document-shaped data: data that's naturally nested and self-contained (a user profile with embedded preferences, a product catalog entry with variable attributes) maps directly onto MongoDB's model without the joins a relational schema would require
  • Built-in horizontal scaling: MongoDB's sharding is a first-class, well-documented feature, designed from early on for distributing data across many servers
  • Fast for single-document reads and writes: when your access pattern is "fetch this whole record by ID," retrieving one self-contained document is often simpler and faster than assembling it from several joined tables

Where it struggles:

  • Weaker guarantees without careful design: MongoDB does support transactions, but relational integrity like foreign key constraints isn't enforced the way it is in PostgreSQL by default, so invalid references can silently creep in if the application doesn't catch them
  • Operational issues can be more disruptive: the Shippable team's four-hour outage traced directly to how MongoDB handled index rebuilding under load, a real, documented failure mode at scale
  • Querying across relationships is harder: modeling genuinely relational data (customers, their orders, those orders' line items, as separate connected entities) in MongoDB often means duplicating data across documents or writing more complex application-side logic to join it yourself
  • Schema-less can become schema-chaos: without discipline, a flexible schema can drift into a collection full of inconsistent documents that are genuinely hard to query and reason about later

Who this suits: applications with naturally document-shaped data, early-stage products where the data model is still actively evolving, and systems that need to scale horizontally across many servers from the start.

Side-by-Side Comparison

PostgreSQL MongoDB
Data model Tables, rows, columns Flexible JSON-like documents
Schema Enforced by the database Flexible, enforced by convention or app code
Relationships Native, via joins and foreign keys Modeled via embedding or manual references
Transactions Full ACID, mature and well-tested Supported, less central to the model historically
Horizontal scaling Possible, more manual setup Built-in, first-class sharding
Query language SQL MongoDB Query Language (JSON-like syntax)
Best for Related, structured data, correctness-critical systems Document-shaped data, rapidly evolving schemas
Documented failure mode Migration and schema-change overhead at scale Index rebuilds and operational issues under load

How This Fits a Career Path

  • Backend Engineer (general): SQL and relational thinking are close to a universal requirement, and understanding PostgreSQL well transfers to nearly every other relational database you'll encounter
  • Data Engineer: both come up constantly, but relational modeling, normalization, and SQL are foundational skills this role assumes; see our Data Engineer roadmap for how this fits into broader pipeline work
  • Full-stack or product-focused roles: MongoDB's document model often maps naturally onto JavaScript-heavy stacks, which is part of why it's historically popular in Node.js-based projects
  • System design interviews: be ready to justify a database choice using the same reasoning Shippable and Agenta used, a specific access pattern and a specific, measured problem, not a format preference

How to Choose Without Overthinking It

  1. Start with your data's actual shape. Clearly related entities (customers, orders, products)? PostgreSQL's relational model fits naturally. Self-contained, nested, variably-structured records? MongoDB's document model fits naturally.
  2. Consider how much you need enforced correctness. If invalid or inconsistent data would cause real business problems (financial records, inventory counts), PostgreSQL's constraints and transactions do real protective work for you.
  3. Don't choose MongoDB "for flexibility" without a genuine need for it. Flexible schemas are a real benefit for a genuinely evolving data model, not a reason to skip schema design thinking altogether.
  4. Remember PostgreSQL's JSONB support before assuming you need a separate document database. A lot of "we need MongoDB for flexible data" problems can be solved with a JSONB column inside an otherwise relational Postgres schema, keeping transactions and joins for everything else.

A note on honesty: the FOSDEM benchmark above found Postgres running tens of percent to three times faster than MongoDB in one specific JSON workload test, and Agenta measured up to 10x gains going the opposite direction. Benchmarks like these depend heavily on the specific workload, schema design, and configuration being tested. Treat any single number, including the ones in this post, as a reason to measure your own system, not as a universal verdict.

Common Mistakes When Learning Databases

  • Picking MongoDB because the data "feels like JSON." Plenty of JSON-shaped data is still genuinely relational underneath, and PostgreSQL's JSONB support often covers the flexibility you actually need.
  • Skipping schema design because NoSQL "doesn't need one." MongoDB not enforcing a schema doesn't mean your application doesn't have one; it just means the database won't catch you when you violate it.
  • Underestimating operational differences. Shippable's four-hour outage wasn't a MongoDB bug; it was a real operational characteristic of how indexes rebuild under load. Learn your database's actual maintenance behavior before you're depending on it at scale.
  • Assuming NoSQL automatically means "scales better." Both databases scale well with the right design; MongoDB's sharding is more built-in, but PostgreSQL handles substantial scale for the vast majority of real applications without ever needing to shard.
  • Treating this as a permanent, un-revisitable choice. Both Shippable's and Agenta's stories are migrations, real companies that changed direction once their actual usage patterns revealed a genuine mismatch.

Frequently Asked Questions

Should a beginner learn SQL or MongoDB first?

SQL, and specifically PostgreSQL. Relational thinking, joins, and normalization are foundational skills that transfer to nearly every other database you'll encounter, including understanding when a document database would actually help.

Is MongoDB being phased out in favor of SQL databases?

No. Both remain widely used in production, often by the same companies for different parts of their system. The Shippable and Agenta stories are real migrations, not evidence that one database is disappearing.

Can PostgreSQL handle large-scale, high-traffic applications?

Yes, extensively. Many very large, high-traffic systems run on PostgreSQL. Horizontal scaling requires more deliberate setup than MongoDB's built-in sharding, but the vast majority of applications reach significant scale on PostgreSQL alone.

When does MongoDB's flexible schema actually pay off?

When your data is genuinely variable in structure, different records honestly have different shapes, not just different values and when your application's data model is still actively evolving during early development, rather than pretending its shape is settled.

Does using MongoDB mean I don't need to think about data structure?

No. Skipping schema design just moves the responsibility for consistency into your application code, where it's genuinely easier to get wrong, not somewhere it disappears.

How do interviewers evaluate this topic in system design interviews?

They're typically testing whether you can reason about a specific access pattern and justify a choice for it, not whether you have a fixed database preference. Being able to explain a trade-off, the way Shippable's and Agenta's real migrations illustrate, matters more than reciting definitions.

Measure Your Own Access Patterns

The real lesson from Shippable's outage and Agenta's speedup isn't "always pick one," it's that both teams made their decision based on their actual, measured access patterns, not a general reputation. Explore the Data Engineer roadmap to build the relational and document-modeling skills that let you make that same kind of evidence-based call on your own projects.

Top comments (0)