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
10 engineers · 4 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
4 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".
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.
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.