1 /

Solutions Architect Competitive Briefing

Database Architecture
Showdown

MongoDB vs. CockroachDB, ScyllaDB, EDB Postgres, and DynamoDB — architecture, transactions, scaling, and positioning.

CockroachDB ScyllaDB EDB Postgres DynamoDB

Scroll or press ↓ to begin

Agenda

01

Architecture Overview

5-way philosophy comparison

02

Head-to-Head Battles

4 deep dives with code & diagrams

03

Feature Matrix & Scaling

Cross-database comparison table

04

Positioning

When to compete, when to concede

Section 01 — Architecture Overview

Five Philosophies, One Problem

MongoDB

General-purpose document database. Flexible schema, rich querying, multi-document ACID, horizontal scaling via sharding. Tunable consistency.

B-TreeWiredTiger

CockroachDB

Geo-distributed SQL. Serializable ACID everywhere. PostgreSQL wire protocol. Raft consensus. Designed for global consistency above all else.

Pebble LSMRaft

ScyllaDB

Raw throughput engine. Shard-per-core architecture. LSM-tree storage. Cassandra-compatible API. Lightweight Transactions only.

LSM-TreeC++

EDB Postgres

Enterprise PostgreSQL. Relational + JSONB. Rich extension ecosystem (PostGIS, Citus). Oracle migration path. MVCC concurrency.

B-Tree/GINMVCC

DynamoDB

Serverless key-value. Single-digit ms latency at any scale. Access-pattern-driven design. 20 GSI limit. AWS-only.

LSM-TreeAWS-only

High-Level Comparison

At-a-glance summary across five architectural dimensions (hover for scores).

2 4 6 8 10 Flexibility Consistency Performance Scalability Ecosystem Schema freedom, developer agility ACID guarantees Throughput & latency Horizontal + geo Drivers, tools, community
Database Flex Cons Perf Scale Eco
MongoDB9788.59
CockroachDB410575
ScyllaDB359.584
EDB Postgres58649
DynamoDB567.585

Scores are directional estimates based on architecture, not absolute benchmarks. Use the head-to-head slides for nuance.

Head to Head

MongoDBvsCockroachDB

Flexible document model with tunable consistency vs. geo-distributed SQL with serializable ACID everywhere.

CockroachDB — Architecture & Transactions

Flexibility vs. Global Consistency

Hover over any component to learn more

MongoDB Replica Set Application (Driver) Primary WiredTiger · B-Tree · ACID oplog oplog Secondary read replica · failover Secondary read replica · failover Tunable consistency · Snapshot isolation · Live resharding vs CockroachDB Raft Consensus SQL Gateway (any node) Node 1 Leader Node 2 Follower Node 3 Follower Serializable ACID · Pebble LSM · Geo-partitioning Every write = multi-node Raft consensus

MongoDB

Model: Document (BSON). Flexible schema. Embedded objects & arrays are first-class.

Transactions: Multi-document ACID. Tunable read/write concern per operation. Snapshot isolation.

Scaling: Sharding via mongos router. Shard key selection is critical. Live resharding available.

CockroachDB

Model: Relational (SQL). Strict schema. PostgreSQL wire-compatible. JSONB column type for semi-structured.

Transactions: Serializable ACID by default (strongest level). Automatic retry on contention. Raft consensus for distributed writes.

Scaling: Automatic range splitting. Data redistributed as nodes are added. Geo-partitioning is a core feature.

Key differentiator: CockroachDB's global consistency comes at a performance cost — every write requires multi-region Raft consensus (speed-of-light latency). MongoDB's tunable consistency lets you trade consistency for latency where appropriate. MongoDB Transactions → · CRDB Architecture →

Query & Data Model Comparison

MongoDB's rich document model vs. CockroachDB's relational approach — how they handle the same e-commerce order.

MongoDB — Single Document

// One document = one atomic unit
db.orders.insertOne({
  customer: "alice",
  items: [
    { sku: "BOOT-42", qty: 1, price: 129.99 },
    { sku: "SOCK-M", qty: 3, price: 12.99 }
  ],
  shipping: { method: "express", addr: {...} },
  total: 168.96
})

Entire order is one document. No joins. Atomic by default.

CockroachDB — Normalized Tables

-- 3 tables, foreign keys, JOINs required
INSERT INTO orders (customer, total)
  VALUES ('alice', 168.96);

INSERT INTO order_items (order_id, sku, qty, price)
  VALUES (1, 'BOOT-42', 1, 129.99),
         (1, 'SOCK-M', 3, 12.99);

INSERT INTO shipping (order_id, method)
  VALUES (1, 'express');

3 tables, 3 inserts, requires a transaction wrapper.

Schema evolution: Adding a giftWrap field in MongoDB? Just add it. In CockroachDB? ALTER TABLE, migration scripts, deployment coordination. Every schema change is a production event.

Head to Head

MongoDBvsScyllaDB

General-purpose document database vs. C++ shard-per-core throughput engine built for known access patterns.

ScyllaDB — Architecture & Transactions

General Purpose vs. Raw Throughput

Hover over any component to learn more

MongoDB — WiredTiger (B-Tree) mongod WiredTiger · B-Tree · ACID · Compression compound idx geo idx text idx wild idx Unlimited secondary indexes — ad-hoc querying on any field New query? Add an index. No table redesign. vs ScyllaDB — Shard-per-Core (LSM) Seastar C++ Engine LSM-Tree · Shard-per-Core · Zero GC CPU 0 shard CPU 1 shard CPU 2 shard CPU 3 shard Each CPU core owns its data slice — zero contention New query pattern? Build a new denormalized table.

MongoDB

Storage: WiredTiger (B-Tree). Balanced read/write performance. Compression.

Transactions: Multi-document ACID. Snapshot isolation. Full rollback support.

Indexing: Unlimited secondary indexes. Compound, multikey, text, vector, geospatial, wildcard. Rich ad-hoc querying.

ScyllaDB

Storage: LSM-Tree. Write-optimized. Shard-per-core — each CPU core owns its data slice. Zero contention.

Transactions: Lightweight Transactions only (compare-and-set via Paxos). No multi-row ACID. Significant LWT performance penalty.

Indexing: Primary key is the index. Secondary indexes are "materialized views." New query pattern = new table design.

ScyllaDB's trade-off: Extreme throughput for partition-key lookups, but no multi-row transactions, no flexible secondary indexes, no ad-hoc querying. Every new access pattern requires a new table. ScyllaDB Architecture →

The Access Pattern Problem

ScyllaDB requires you to know every query upfront. New query pattern? New denormalized table.

MongoDB — Ad-hoc Querying

// Query any field, any time
db.events.find({
  userId: "u_123",
  type: "click",
  timestamp: { $gte: ISODate("2025-01-01") }
}).sort({ timestamp: -1 })

// New requirement? Just add an index:
db.events.createIndex({ type: 1, timestamp: -1 })

ScyllaDB — Partition-Key Only

-- Table designed for ONE access pattern
CREATE TABLE events_by_user (
  user_id text,
  timestamp timestamp,
  type text,
  PRIMARY KEY (user_id, timestamp)
);

-- Need by type? NEW TABLE:
CREATE TABLE events_by_type (
  type text, timestamp timestamp,
  user_id text,
  PRIMARY KEY (type, timestamp)
);
Operational reality: At scale, ScyllaDB tables multiply. A microservice with 5 access patterns needs 5 tables with duplicated data. Write amplification, compaction tuning (STCS vs LCS), tombstone management, and repair operations become significant operational burdens.

Head to Head

MongoDBvsEDB Postgres

Document-native from storage to query language vs. relational database with JSONB columns bolted on.

EDB Postgres — Architecture & Schema

Document-Native vs. Relational + JSONB

Hover over any component to learn more

MongoDB — Document Native { _id: ObjectId("..."), name: "Alice", orders: [ { item: "Boots", qty: 1, price: 129.99 } ], embedding: [0.12, -0.34, ...] } Flexible schema · No DDL · No migrations Add a field? Just add it. No ALTER TABLE. vs EDB Postgres — Relational + JSONB TABLE users id SERIAL | name VARCHAR(100) email VARCHAR(255) | data JSONB FK TABLE orders id | user_id FK | item VARCHAR | qty INT Citus for sharding (extension / bolt-on) ALTER TABLE + VACUUM + bloat management

MongoDB

Schema: Flexible by default. Optional JSON Schema validation. No DDL for schema changes.

BSON: Binary JSON with rich types (Decimal128, Date, ObjectId, Binary). Document is the atomic unit.

Scaling: Native horizontal sharding. Designed for distributed from day one.

EDB Postgres

Schema: Strict DDL. Schema changes require ALTER TABLE. Migration tooling needed.

JSONB: Binary JSON stored in a column. GIN indexes for querying. But you still define relational tables — JSONB is an add-on, not the native model.

Scaling: Primarily scale-up. Citus extension for sharding, but it's a bolt-on. Logical replication for read replicas.

JSONB is not a document database. PostgreSQL's JSONB gives you JSON storage, but querying nested arrays requires verbose SQL syntax. No aggregation pipeline stages, no $elemMatch, no $unwind, and no change streams. EDB Docs →

Querying Nested Data

The same query — find orders with boots over $100 — shows why JSONB isn't a document model.

MongoDB — Natural

db.orders.find({
  "items": {
    $elemMatch: {
      category: "boots",
      price: { $gt: 100 }
    }
  }
})

Reads like the data structure. Works on embedded arrays natively.

PostgreSQL JSONB — Verbose

SELECT * FROM orders
WHERE EXISTS (
  SELECT 1
  FROM jsonb_array_elements(
    data->'items'
  ) AS item
  WHERE item->>'category' = 'boots'
  AND (item->>'price')::numeric > 100
);

Subquery + function call + type casting. Harder to read, write, and maintain.

Scaling ceiling: PostgreSQL scales vertically. Citus adds horizontal sharding but it's an extension — not a native feature. You're managing a distributed system on top of a database that wasn't designed for it. VACUUM overhead, bloat, and connection pooling become significant at scale. PostgreSQL MVCC →

Head to Head

MongoDBvsDynamoDB

Rich querying with multi-cloud freedom vs. AWS-only serverless key-value with access-pattern rigidity.

DynamoDB — Architecture & Indexing

Rich Querying vs. Access-Pattern Rigidity

Hover over any component to learn more

MongoDB Atlas — Multi-Cloud ☁ AWS us-east-1 ☁ Azure eastus ☁ GCP us-central1 Atlas Unified API CRUD · Search · Vector · Streams ∞ secondary indexes — any query pattern No vendor lock-in · Same API on any cloud vs DynamoDB — AWS Only ☁ AWS Region Only No multi-cloud · No exit path PK + SK Base table GSI 1 copy GSI 2-5 copies ⚠ Max 20 GSIs — each access pattern burns one Serverless scaling but rigid access patterns New query? Build a new table or accept you can't.

MongoDB

Indexes: Unlimited secondary indexes. Create new indexes to support new queries without changing the data model.

Transactions: Session-based multi-document ACID. Cross-collection, cross-shard.

Platform: Multi-cloud (AWS, Azure, GCP). Full-text search, vector search, change streams — all built-in.

DynamoDB

Indexes: Max 20 Global Secondary Indexes (GSIs). Each GSI is a separate table projection. New access pattern = new GSI or table restructuring.

Transactions: API-based (TransactWriteItems / TransactGetItems). Max 100 items per transaction. No session concept.

Platform: AWS-only. Full-text search requires OpenSearch. No built-in vector search. Streams exist but limited.

DynamoDB's rigidity: Single-table design is an art form — but it makes your data model incredibly brittle. Adding a new access pattern months later can require a full data migration. AWS vendor lock-in is absolute — there is no multi-cloud DynamoDB. DynamoDB Docs →

The Lock-In Tax

DynamoDB's serverless convenience comes with a hidden cost — absolute vendor dependency and ecosystem lock-in.

No Exit Strategy

DynamoDB's data model (partition key + sort key + GSIs) is proprietary. Migration requires rewriting your data layer — not just moving data. No wire-compatible alternative exists.

20 GSI Ceiling

Every access pattern burns a GSI. At 20 you're done. MongoDB has unlimited secondary indexes — create them on the fly without restructuring the data model.

No Search, No Vectors

Full-text search requires OpenSearch (separate service, separate bill). Vector search requires a 3rd-party service. MongoDB Atlas has both built-in.

DynamoDB Shines At

Simple key-value workloads at any scale with zero ops. Serverless microservices on AWS Lambda. Session stores, feature flags, game leaderboards — simple patterns where the 20 GSI limit isn't a concern.

MongoDB's Counter

Atlas Serverless offers zero-ops with multi-cloud flexibility, unlimited indexes, rich querying, ACID transactions, and no vendor lock-in. Same convenience, more capability, more freedom.

Section 03 — Scaling Deep Dive

Scaling from GB to TB+

How each database handles data growth — and where the pain points emerge.

MongoDB

≤ 50 GB Single replica set. Read preference secondaryPreferred for analytics. M10–M30 Atlas tier.
50–500 GB Scale up instance tier (M40–M60). Add dedicated Atlas Search Nodes for Lucene workloads. Read/write concern tuning. Zone-aware sharding for compliance.
0.5–5 TB Shard key selection is the critical decision. Live resharding lets you change shard keys without downtime. Hash vs range sharding. Scatter-gather for non-targeted queries.
5 TB+ Global Clusters for geo-distributed writes. Zone sharding pins data to regions. Atlas auto-scaling. Dedicated search nodes scale independently from the database tier.

Sharding docs · Atlas Auto-Scaling

CockroachDB

≤ 50 GB 3-node cluster, auto range splitting. Seamless horizontal scale-out by adding nodes.
50–500 GB Geo-partitioning (PARTITION BY) for data locality. Hot ranges require careful primary key design to avoid sequential writes.
0.5–5 TB Cross-region Raft consensus = speed-of-light write latency. 100ms+ for multi-region writes. Follower reads can mitigate read latency.
5 TB+ Pain point: Global writes are bottlenecked by physics. Large scans across ranges expensive. Careful to avoid hot-spot keys (UUID > SERIAL).

Distribution Layer docs

ScyllaDB

≤ 50 GB 3-node cluster with vNodes. Linear throughput scaling by adding nodes. STCS compaction.
50–500 GB Compaction strategy is critical: STCS for write-heavy, LCS for read-heavy. Incremental Compaction Strategy (ICS) in Enterprise for large datasets. Repair operations start to matter.
0.5–5 TB Pain point: Hot partitions from skewed data. Tombstone accumulation degrades read performance. Must model for partition-key access or accept full table scans.
5 TB+ Multi-DC replication (eventual consistency). Repair becomes expensive. No ad-hoc queries — every query must be pre-planned in the data model.

ScyllaDB Architecture docs

EDB Postgres

≤ 50 GB Single instance. Straightforward. Read replicas for HA.
50–500 GB Scale-up (bigger instance). Table partitioning. VACUUM overhead grows — autovacuum tuning needed.
0.5–5 TB Citus extension for sharding (bolt-on). Distribution column selection is permanent. Bloat management.
5 TB+ Pain point: VACUUM is now a full-time ops concern. Connection pooling (PgBouncer) required. Bloat can consume 30%+ disk.

EDB docs

DynamoDB

≤ 50 GB Serverless auto-scales. On-demand or provisioned capacity. Simple.
50–500 GB GSI overhead grows (each GSI duplicates storage). Hot partitions from uneven key distribution. Adaptive capacity helps but doesn't eliminate.
0.5–5 TB Cost scales linearly with no volume discounts. GSI limit (20) becomes painful — every new access pattern burns one.
5 TB+ Pain point: Global Tables for multi-region but eventual consistency only. Cost can exceed MongoDB Atlas at this tier. No exit strategy.

Partition design guide

MongoDB's scaling advantage: Live resharding, auto-scaling tiers, and zone-aware sharding mean you can start with a replica set and shard when you need to — without redesigning your data model. Competitors either require upfront data modeling decisions (DynamoDB, ScyllaDB) or bolt-on extensions (Postgres/Citus).

Feature Comparison Matrix

CapabilityMongoDBCockroachDBScyllaDBEDB PostgresDynamoDB
Data ModelDocument (BSON)Relational (SQL)Wide-column (CQL)Relational + JSONBKey-Value / Document
Multi-doc ACID✓ Full✓ Serializable✗ LWT only✓ Full△ 100 items max
SchemaFlexibleStrict DDLStrict DDLStrict DDLSchemaless
Secondary indexesUnlimitedUnlimitedLimited (MVs)Unlimited20 GSIs max
Full-text search✓ Atlas Search✗ External✗ External△ pg_trgm / FTS✗ OpenSearch
Vector search✓ $vectorSearch✗ None✗ None△ pgvector✗ None
Change streams / CDC✓ Real-time✓ Changefeeds△ CDC (experimental)△ Logical replication✓ DynamoDB Streams
Horizontal scaling✓ Sharding✓ Auto range-split✓ Consistent hashing△ Citus (add-on)✓ Auto (serverless)
Multi-cloudAWS/Azure/GCPAWS/Azure/GCPAWS/Azure/GCPAWS/Azure/GCPAWS only
Geo-distributionGlobal ClustersNative geo-partitioning△ Multi-DC replication✗ Read replicas only△ Global Tables (eventual)
Client-side encryption✓ FLE / Queryable✗ None✗ None✗ None✗ Server-side only

Sources: MongoDB · CockroachDB · ScyllaDB · EDB · DynamoDB

Enterprise Readiness

CapabilityMongoDB AtlasCockroachDBScyllaDBEDB PostgresDynamoDB
SLA99.995%99.999% (Dedicated)99.99% (Cloud)99.95%+99.999% (Global Tables)
ComplianceSOC2, HIPAA, PCI, ISO, FedRAMPSOC2, HIPAASOC2SOC2, HIPAA, PCISOC2, HIPAA, PCI, FedRAMP
BackupContinuous PITRIncremental + PITRSnapshot-basedpgBackRest / PITROn-demand + PITR
Ops complexityManaged — Atlas automatesManaged — auto-scalingSelf-managed requires tuningDBA expertise neededServerless — zero ops
Section 04 — Positioning

When to Compete, When to Concede

MongoDB Wins When…

  • Application needs flexible schema and rich document model
  • OLTP + search + vectors in one platform — eliminate bolt-on architecture
  • Team values developer velocity over DBA-driven operations
  • Multi-cloud is a requirement (not locked to AWS or GCP)
  • Data has nested structures, polymorphic schemas, or evolving models
  • Need real-time change streams for event-driven architecture

CockroachDB wins when…

Global serializable ACID is non-negotiable. Financial ledgers, payment systems, global inventory. Customer already uses PostgreSQL and needs distributed SQL.

ScyllaDB wins when…

Workload is partition-key lookups at massive throughput. Time-series ingestion, IoT telemetry, messaging backends. No complex querying or transactions needed.

EDB Postgres wins when…

Customer is migrating from Oracle and wants SQL compatibility. Extension ecosystem (PostGIS, TimescaleDB) is critical. Team has deep relational expertise.

DynamoDB wins when…

All-in AWS with serverless architecture. Simple key-value access patterns. Team accepts vendor lock-in for zero-ops experience.

Battlecard — Key Talking Points

Against CockroachDB

"Serializable everywhere = slow everywhere." Every write crosses regions via Raft. MongoDB lets you tune consistency per operation.
"No native search or vector." CockroachDB has no built-in full-text or vector search. You'll need a sidecar.

Against ScyllaDB

"No transactions, no ad-hoc queries." LWT is compare-and-set, not ACID. Every new query pattern requires a new table.
"Great for one thing." Partition-key lookups at massive scale. But real applications need more.

Against EDB Postgres

"JSONB isn't a document database." Verbose SQL for nested queries. No aggregation pipeline. No change streams. Scale-up ceiling.
"Citus is a bolt-on." Horizontal scaling isn't native. It's an extension with limitations.

Against DynamoDB

"20 GSIs and you're done." Every new query pattern burns a GSI. Then what? Redesign the table.
"AWS lock-in is absolute." No multi-cloud. No on-prem. No exit strategy.
"No search, no vectors." Full-text requires OpenSearch. Vectors require a separate service. Two bills, two APIs.

References & Further Reading

End of Briefing

Questions & Discussion

Know each competitor's sweet spot. Compete on developer experience, platform breadth, and architectural simplicity.

MongoDB Solutions Architecture