Home/Technologies/PostgreSQL
Technology · Cloud & data

PostgreSQL and MongoDB, chosen by the shape of the data.

Relational for ledgers, rules and anything money touches; documents where the shape varies by tenant. Engineers who model, tune, migrate and operate both under our own products.

PostgreSQLWhat we build with it
01Systems of record
02Multi-tenant SaaS data models
03Catalogues, profiles and content in MongoDB
04Performance and query tuning
05Staged migrations
06Change data capture and event feeds
Usually runs with
  1. PostgreSQL
  2. MongoDB
  3. Redis
  4. PgBouncer
  5. Debezium
  6. Kafka
Why we use them

PostgreSQL is the default store under everything we build.

A loyalty ledger, a sales-compensation plan, a freight settlement, a procurement approval — each is a set of facts with relationships and invariants, and a relational database with real transactions, constraints and a mature query planner enforces those invariants where they belong. It is part of the stack our own products — Loyalty & Retention, Sales Performance, Order & Supply Management and Workflow & Procurement — run on, and its JSONB columns cover many of the cases where someone once reached for a document store.

MongoDB earns its place where the shape of the data genuinely varies: a product catalogue with different attributes per category, a member profile that each tenant extends differently, a content model that editors change weekly, high-volume event and session data that is read back by key. Modelled around the access pattern rather than against it, it is fast, easy to shard and pleasant to work with from Node.js.

When we don’t: we do not put money, quotas or approvals in a document store, and we do not force a fixed schema on data that has none. Analytics belongs in a warehouse — see Data Engineering — and caches belong in Redis, not in either of these.

What we build with them

Six things we do with PostgreSQL and MongoDB.

01

Systems of record

Normalised PostgreSQL schemas for ledgers, plans, orders and approvals, with constraints, foreign keys and append-only audit tables so the database refuses bad data before the application has to.

02

Multi-tenant SaaS data models

Row-level security, tenant-scoped indexes and pooled connections for platforms that serve many clients from one estate — the model a multi-tenant product needs from its first tenant.

03

Catalogues, profiles and content in MongoDB

Document models designed from the read patterns: embedded where data is read together, referenced where it changes independently, with schema validation so flexibility does not become drift.

04

Performance and query tuning

Index review, plan analysis, partitioning of time-series tables and connection pooling with PgBouncer — the largest gains usually come from the slowest queries, long before anyone buys a bigger instance.

05

Staged migrations

Expand-and-contract schema changes, backfills in batches, and moves from Oracle, SQL Server or MySQL to PostgreSQL with rehearsed cutovers during a re-engineering programme.

06

Change data capture and event feeds

Debezium on the write-ahead log and the outbox pattern turn the database into a reliable event source for Kafka consumers — no dual writes.

Fit

When to choose which.

Right fit

Choose PostgreSQL when the data has relationships and rules: anything financial, anything audited, anything with a workflow, anything reporting will later join across. It is the safe default for transactional systems and it scales further than many teams assume — partitioning, read replicas and a managed service take a single primary a very long way. Choose MongoDB when documents are the natural unit, schemas vary by tenant or category, writes are high-volume and reads are by key, and horizontal sharding is a real requirement rather than a forecast.

Look elsewhere

Do not choose MongoDB because the team dislikes migrations; schema changes still happen, they just stop being visible. Do not choose PostgreSQL for a workload that is mostly unstructured payloads read by identifier at very high rates, where a document store or a key-value cache is cheaper and simpler. And do not choose either for analytics across billions of rows — that is a warehouse or a lakehouse, fed by change data capture from the operational store.

In practice

A ledger table designed to refuse bad data.

0042_points_ledger.sqlsql
create table points_ledger (
  id           bigint generated always as identity primary key,
  member_id    uuid not null references members(id),
  amount       integer not null check (amount <> 0),
  reason       text not null,
  idempotency  text not null unique,
  -- flexible per-tenant attributes live in JSONB, not in a second database
  attrs        jsonb not null default '{}',
  created_at   timestamptz not null default now()
) partition by range (created_at);
-- append-only: no update or delete grants on this table
create index concurrently on points_ledger (member_id, created_at desc);
+ alter table points_ledger enable row level security;
Reference architecture

Where each store sits in a typical estate.

Applications
APIs & servicesBatch & rating jobsAdmin & portals
Operational stores
PostgreSQL primary + replicasMongoDB replica setRedis cachePgBouncer
Change & events
Outbox tablesDebezium CDCKafka topics
Downstream
Warehouse / lakehouseSearch indexPower BIBackups & PITR
Our standards

What the databases we hand over have.

  • Migrations in version control, forward-only, reviewed in pull requests and applied by the pipeline — with Flyway, Prisma, Alembic or Liquibase depending on the application stack. No manual DDL in production.
  • Constraints in the database, not only in code. Foreign keys, check constraints, unique indexes and MongoDB schema validation, so every application that ever touches the data is held to the same rules.
  • Backups that have been restored. Point-in-time recovery enabled, restores rehearsed on a schedule, and the recovery time and recovery point written into the runbook as numbers.
  • Managed services by default — RDS or Aurora, Azure Database, Cloud SQL, MongoDB Atlas — with encryption at rest, private networking and audit logging on; self-hosted only where residency law requires it.
  • Observability on the store itself: slow-query logs, pg_stat_statements or Atlas profiler reviewed regularly, at a rhythm agreed with you, and alerts on replication lag and connection saturation.
  • Least-privilege roles per service, secrets rotated from a vault, row-level security where tenants share tables, and personal data mapped for GDPR / KVKK erasure and retention.
  • Load tested against production-shaped data. Realistic volumes, realistic skew, and the query plans that passed captured with the release.
  • A data dictionary — every table or collection, its owner, its retention and what depends on it — so the next team does not have to reverse-engineer the schema.
Typical pairings

What usually ships alongside the schema.

  • An entity model and access-pattern review before the first migration is written
  • The migration set, seed data and rollback procedure, run by CI in every environment
  • Index and query-plan report with before-and-after timings for the slowest queries
  • Terraform for the managed instances, replicas, parameter groups and backup policy
  • Dashboards and alert rules for latency, replication lag, connections, bloat and disk
  • A runbook covering failover, restore, major-version upgrade and the CDC replay procedure
Usually runs with
PostgreSQLMongoDBRedisPgBouncerDebeziumKafkaPrismaFlywayTerraformAWSAzureGoogle Cloud
FAQ

Frequently asked questions

Usually PostgreSQL, and we will show you why on your own entity model. If your data is a set of related facts with rules, it is relational. If it is documents with varying shape read back by key, MongoDB fits. Many estates run both, each doing the job it is good at.
Usually, yes. A well-indexed, partitioned PostgreSQL on a managed service with read replicas scales further than many teams assume. Scale problems are far more often query and index problems than engine problems, and we fix those first.
Yes. We inventory the schema, procedures and the applications that depend on them, convert in stages, run both databases in parallel with change data capture, and cut over per application with a rehearsed rollback. The PL/SQL is usually the long pole, and we tell you that up front.
Both. Through DevOps & Cloud we operate the managed instances under our own products and under client estates — backups, failover, upgrades, tuning — with the same SLO discipline as the rest of the platform.
In line with GDPR / KVKK: personal fields are catalogued, encrypted where the risk warrants it, scoped by row-level security in shared tables, and covered by an erasure and retention procedure that the application and the CDC feed both respect.
Related

Neighbouring stacks and the services that use them.

Have a schema that has stopped keeping up?

Send us the slowest query or the entity model you are arguing about. A database engineer reads it and replies in writing with how we would approach it.

✓ No pitch deck✓ Reply from an AI-native engineer✓ Written follow-up