Why PostgreSQL instead of MongoDB for an order management system?
Consistency ↔ Flexibility
Context
Choose the primary datastore for orders, payments and fulfilment.
Context
We're building an order management platform: orders, line items, payments, refunds, shipments. Product keeps asking for "custom attributes" per merchant, which is what started the MongoDB conversation.
Option A — PostgreSQL
Relational core with jsonb for merchant-specific attributes. Transactions across orders, payments and inventory reservations.
Option B — MongoDB
Embed line items and shipments in the order document. Schema-less custom attributes. Multi-document transactions exist since 4.0.
Question
Given money moves through this system, is there any scenario where MongoDB is the better primary store? Or is jsonb enough for the flexibility we need?
Constraints
- Team
- 8 engineers
- Data
- ~50M orders/yr
- Compliance
- PCI-adjacent
PostgreSQLvsMongoDB
Community verdict
9 engineers · 7 opinions
With these constraints, what would you choose?
One choice per engineer. You can change it any time.
Schema flexibility →
Trade-offs
Dimensions
- Consistency
- 5PostgreSQL scores 5 of 53MongoDB scores 3 of 5
- Schema flexibility
- 3PostgreSQL scores 3 of 55MongoDB scores 5 of 5
- Reporting
- 5PostgreSQL scores 5 of 5
Community discussion
7 comments
Have you made this decision in production? Share your reasoning.
Sign in to commentReporting is the underrated factor. Your BI team can point Metabase at a Postgres read replica on day one. With Mongo you are building an ETL pipeline before anyone can answer "revenue by region".
Playing devil's advocate: if the order document is always read and written whole, by one service, Mongo's document model maps to it nicely. The trouble starts the day a second team needs a different shape of the same data.
Money + multi-entity invariants = relational. A refund touches the order, the payment, the ledger and inventory. You want one ACID transaction and foreign keys that make illegal states unrepresentable.
jsonbwith a GIN index covers merchant attributes fine. We run 200M rows like that.This matches what we prototyped. The custom-attribute queries were fast enough with a GIN index on the jsonb column.
Orders end up in finance reports, and finance reports are joins. Every Mongo-backed order system I have seen grew a nightly ETL into a relational warehouse just to answer "revenue by region last quarter".
And JSONB covers the genuinely schemaless bits, like per-marketplace metadata, without giving up the joins.
Devil's advocate: if orders are truly aggregate-shaped and you never join across them, Mongo's document model matches the domain well. The problem is finance will ask for joins on day two.