Why I put Postgres and MongoDB in the same project
Using two databases sounds like over-engineering until you look at what each table actually needs — strict schema and foreign keys, or a firehose of activity nobody will ever join a query against.
Hammad Iqbal
Software Engineer
An invoicing and payment-tracking app is, at its core, a relational problem — but the internal activity feed sitting next to it was a different shape of data entirely, and forcing both into one schema was the wrong kind of consistency.
- Invoices, payments, and users need foreign keys and transactions — that's a relational job.
- An activity log is closer to a stream than a table, and forcing it through migrations is friction with no payoff.
- A second database is more ops overhead than one — worth it only when a table's shape actually disagrees with the rest of the schema.
Prisma and Postgres for anything that touches money
Invoice and payment records benefit from exactly what a relational database is built for: foreign key constraints that make an orphaned payment impossible, and transactions that guarantee an invoice update and its payment record either both land or neither does. That's not a place to get creative with schema flexibility.
MongoDB for the activity feed nobody joins against
The activity log records a different event shape for every action type — a status change looks nothing like a comment, which looks nothing like a bulk import. Forcing that through a relational migration every time a new event type shipped was friction with no real payoff, since the feed is read chronologically and never joined against the rest of the schema.
- Structured, relational data → Postgres + Prisma
- High-volume, shape-varying event data → a document store
- If you're not sure, start with Postgres — the exception should earn its place, not the default
Two databases is a cost, not a flex
Running both means two things to back up, two connections to manage in the container setup, and two failure modes to reason about during an incident. That overhead is worth paying when a specific table's access pattern genuinely conflicts with the rest of the schema — it's not worth paying by default because it looks like a more serious architecture.
Reach for a second database when a specific piece of data disagrees with your schema, not because more databases seems more impressive. One table's shape doesn't have to dictate the rest of the project's.
Have a project this kind of thinking applies to?
Tell me what you're building — I read every message myself.