Database Comparison — PostgreSQL vs MySQL vs CockroachDB¶
Canonical comparison of the three dominant relational database systems.
Quick Reference¶
| Dimension | PostgreSQL | MySQL | CockroachDB |
|---|---|---|---|
| Latest Version | v18.3 (Feb 2026) | 8.4 LTS / 9.x Innovation | v26.1 (2026) |
| Architecture | Single-node (primary + replicas) | Single-node (primary + replicas) | Distributed (multi-node, symmetric) |
| Scaling Model | Vertical (read replicas for reads) | Vertical (read replicas, Group Repl.) | Horizontal (automatic sharding) |
| Consistency | Strong (single node) | Strong (single node) | Serializable (distributed) |
| Wire Protocol | PostgreSQL | MySQL | PostgreSQL-compatible |
| License | PostgreSQL (MIT-like) | GPL 2.0 / Commercial | BSL 1.1 / CCL |
| Company | Community | Oracle | Cockroach Labs |
Feature Matrix¶
| Feature | PostgreSQL | MySQL | CockroachDB |
|---|---|---|---|
| ACID | ✅ Full | ✅ Full (InnoDB) | ✅ Serializable |
| JSON/Document | ✅ JSONB (binary, indexed) | ✅ JSON | ✅ JSONB (PG compat) |
| Full-text search | ✅ Built-in | ✅ Built-in | ⚠️ Basic |
| Geo/Spatial | ✅ PostGIS | ✅ Spatial | ✅ Built-in |
| Vector search | ✅ pgvector extension | ❌ (HeatWave GenAI) | ✅ Built-in (v26.1) |
| Async I/O | ✅ io_uring (v18) | ❌ | ❌ |
| Horizontal write scaling | ❌ (Citus extension) | ❌ (Group Repl. limited) | ✅ Native |
| Multi-region active-active | ❌ | ❌ | ✅ Native |
| Survive datacenter failure | ❌ (manual failover) | ❌ (manual failover) | ✅ Automatic |
| Online DDL | ⚠️ (some locking) | ✅ (InnoDB online DDL) | ✅ Zero-downtime |
| Logical replication | ✅ (v18 improved) | ✅ | ✅ CDC |
| Extensions | ✅ Rich (PostGIS, TimescaleDB, etc.) | ⚠️ Limited | ❌ |
Performance Positioning¶
| Workload | Best Choice |
|---|---|
| Single-node OLTP | PostgreSQL (fastest with AIO v18) |
| Single-node mixed OLTP+OLAP | MySQL HeatWave (if Oracle OK) |
| Read-heavy, many replicas | PostgreSQL or MySQL |
| Write-heavy, global distribution | CockroachDB |
| Multi-region, data sovereignty | CockroachDB |
| AI/vector search | PostgreSQL (pgvector) or CockroachDB |
Decision Guide¶
| Scenario | Recommendation |
|---|---|
| General-purpose backend | PostgreSQL — most features, most extensions |
| WordPress / PHP ecosystem | MySQL — deepest PHP/Laravel integration |
| Global application, multi-region | CockroachDB — survive anything |
| Maximum OLTP performance (single-region) | PostgreSQL 18 — AIO + io_uring |
| Combined OLTP + analytics | MySQL HeatWave (managed) or PG + TimescaleDB |
| Regulatory data sovereignty | CockroachDB — geo-partitioned data |
| Budget-conscious, open-source | PostgreSQL (most permissive license) |
| Existing MySQL workloads | MySQL 8.4 LTS → plan 9.x migration |
Replication Models¶
PostgreSQL — WAL Streaming Replication¶
PostgreSQL uses a primary-standby architecture with Write-Ahead Log (WAL) streaming. There is no distributed consensus protocol — the primary is the single authoritative source.
- Mechanism: Every write is first recorded in the WAL. The WAL sender process on the primary streams WAL records to the WAL receiver process on each standby in near-real-time
- Topology: 1:N (one primary, multiple standbys). Supports cascading replication (standby ships WAL to another standby)
- Sync modes: Asynchronous by default. Synchronous mode available via
synchronous_standby_names— each commit waits for standby confirmation before returning to the client - Logical replication: Supported since v10. Allows selective table replication, cross-version replication, and pub/sub patterns. Improved significantly in v18
- Failover: Requires external tools — Patroni, pg_auto_failover, or PgBouncer. No built-in automatic failover
MySQL — Group Replication (Paxos / XCom)¶
MySQL offers traditional async replication plus Group Replication (GR), which uses a Paxos-based consensus protocol called XCom (a Mencius variant).
- Consensus: Transactions are broadcast to all group members via XCom. Each member independently certifies the transaction by checking for write-set conflicts. Since certification is deterministic, all members reach the same commit/abort decision
- Single-Primary mode (default): One member accepts writes; others are read-only. Automatic leader election on primary failure
- Multi-Primary mode: All members accept writes simultaneously. Write conflicts are detected and one transaction is rolled back
- Fault tolerance: Requires
n = 2f + 1members to tolerateffailures. A 3-node group tolerates 1 failure; a 5-node group tolerates 2 - Single consensus leader: MySQL 8.0.27+ supports
group_replication_paxos_single_leaderfor improved throughput in single-primary mode - Semi-sync replication: Alternative to GR — primary waits for at least one replica to acknowledge before returning to client. Simpler than GR but no automatic failover
CockroachDB — Raft Consensus (Per-Range)¶
CockroachDB is natively distributed. Data is split into ranges (default 512 MB), and each range is replicated via the Raft consensus protocol across at least 3 nodes.
- Raft groups: Each range has its own independent Raft group with a leader, followers, and a log. The leader coordinates writes; a majority quorum must acknowledge before commit
- Lease-holder: One replica per range is the "lease-holder" that coordinates reads and writes. The lease-holder is typically (but not always) the Raft leader
- Automatic rebalancing: If a node fails, CockroachDB automatically re-replicates under-replicated ranges to other nodes
- Hybrid Logical Clocks (HLC): CockroachDB uses HLC to maintain causal consistency across distributed nodes, enabling serializable distributed transactions
- No external tools: Failover, rebalancing, and replication are all built into the database — no Patroni, no ProxySQL, no manual intervention
Replication Comparison Matrix¶
| Dimension | PostgreSQL | MySQL (Group Repl.) | CockroachDB |
|---|---|---|---|
| Protocol | WAL streaming (no consensus) | Paxos variant (XCom) | Raft (per-range) |
| Write path | Single primary only | Single or multi-primary | Any node (lease-holder per range) |
| Consensus required | No (primary is authoritative) | Yes (majority quorum) | Yes (majority quorum per range) |
| Automatic failover | No (needs Patroni, etc.) | Yes (within group) | Yes (built-in) |
| Replication lag | Seconds (async) / zero (sync) | Near-zero (virtually synchronous) | Zero (consensus-committed) |
| Max replicas | No hard limit (typical: 2-5) | 9 members per group | 3-7 replicas per range (configurable) |
| Cross-region | Possible but high-latency sync | Possible (InnoDB ClusterSet) | Native (geo-partitioned) |
Consistency Trade-offs¶
CAP Theorem Positioning¶
graph TD
subgraph "CAP Theorem Positioning"
CP["CP Systems\n(Consistency + Partition Tolerance)"]
CA["CA Systems\n(Consistency + Availability)"]
end
PG["PostgreSQL\n(single-node CA;\nCP with sync replication)"] --> CA
MySQL["MySQL\n(single-node CA;\nCP with Group Replication)"] --> CA
CRDB["CockroachDB\n(CP — always consistent,\navailable if majority up)"] --> CP
| Database | CAP Position | Consistency Model | During Partition |
|---|---|---|---|
| PostgreSQL | CA (single-node); CP (sync repl.) | Strong on single node | Primary continues; standbys may lag or disconnect |
| MySQL | CA (single-node); CP (Group Repl.) | Strong on single node | GR blocks writes if no quorum |
| CockroachDB | CP | Serializable (distributed) | Minority ranges become unavailable; majority continues |
Isolation Levels¶
| Level | PostgreSQL | MySQL (InnoDB) | CockroachDB |
|---|---|---|---|
| Read Uncommitted | Treated as Read Committed | Supported | Not supported |
| Read Committed | Default | Default | Supported |
| Repeatable Read | Supported (snapshot isolation) | Supported | Not supported (maps to Serializable) |
| Serializable | Supported (SSI) | Supported (gap locking) | Default (SSI) |
CockroachDB defaults to Serializable
CockroachDB uses Serializable Snapshot Isolation (SSI) by default — the strongest practical isolation level. PostgreSQL defaults to Read Committed, requiring explicit SET TRANSACTION ISOLATION LEVEL SERIALIZABLE. MySQL InnoDB defaults to Repeatable Read with gap locking.
Anomaly Handling¶
| Anomaly | PostgreSQL | MySQL | CockroachDB |
|---|---|---|---|
| Dirty reads | Prevented (all levels) | Possible at Read Uncommitted | Prevented (all levels) |
| Non-repeatable reads | Prevented at RR+ | Prevented at RR+ | Prevented (all levels) |
| Phantom reads | Prevented at Serializable | Prevented at RR (gap locks) | Prevented (all levels) |
| Write skew | Prevented at Serializable (SSI) | Not fully prevented | Prevented (default SSI) |
Migration Paths¶
MySQL to PostgreSQL¶
The most common migration path. Key tools and considerations:
| Tool | Type | Best For | Throughput |
|---|---|---|---|
| pgLoader | Open-source CLI | One-time "big bang" migrations | Up to 3 TB/hr (tuned) |
| AWS DMS | Managed service | Continuous replication / zero-downtime cutover | Varies by instance class |
| Ora2Pg | Open-source CLI | Oracle-to-PG (also handles MySQL) | Medium |
Common pitfalls:
ENUMtypes map differently (MySQL ENUM to PG ENUM or VARCHAR)AUTO_INCREMENTmaps toSERIAL/IDENTITY- MySQL's
TINYINT(1)for booleans needs mapping to PGBOOLEAN - Case sensitivity: MySQL defaults to case-insensitive collation; PG is case-sensitive
- Stored procedures require manual rewrite (MySQL procedural SQL differs significantly from PL/pgSQL)
PostgreSQL to CockroachDB¶
CockroachDB's PostgreSQL wire compatibility makes this the smoothest distributed migration path.
| Tool | Purpose |
|---|---|
| MOLT SCT (Schema Conversion Tool) | Converts PG schema to CockroachDB-compatible DDL |
| MOLT Fetch | Migrates data from PG to CockroachDB |
| MOLT Verify | Validates data integrity post-migration (table, column, row verification) |
| MOLT Live Migration Service | Zero-downtime cutover with continuous replication |
| AWS DMS | Alternative: configure CockroachDB as PG target endpoint |
Key constraints:
- All tables must have explicit primary keys (CockroachDB requirement)
- Some PG extensions are unsupported (PostGIS partial, TimescaleDB no, pg_trgm partial)
SERIALcolumns should be converted toUUIDfor distributed uniqueness- ORM compatibility: most PG-compatible ORMs work unchanged; test with your specific ORM version
MySQL to CockroachDB¶
No direct migration path. The recommended approach:
- MySQL to PostgreSQL (via pgLoader or DMS)
- PostgreSQL to CockroachDB (via MOLT tooling)
Alternatively, use AWS DMS directly — configure MySQL as source, CockroachDB (via PG endpoint) as target.
Managed Service Options¶
| Service | Engine | Provider | Min Price | HA Model | SLA |
|---|---|---|---|---|---|
| RDS for PostgreSQL | PostgreSQL | AWS | ~$15/mo (db.t4g.micro) | Multi-AZ standby | 99.95% |
| RDS for MySQL | MySQL | AWS | ~$15/mo (db.t4g.micro) | Multi-AZ standby | 99.95% |
| Aurora PostgreSQL | PG-compatible | AWS | ~$30/mo (serverless min) | 6-way storage replication | 99.99% |
| Aurora MySQL | MySQL-compatible | AWS | ~$30/mo (serverless min) | 6-way storage replication | 99.99% |
| Cloud SQL | PG / MySQL | GCP | ~$8/mo (shared-core) | Regional HA | 99.95-99.99% |
| AlloyDB | PG-compatible | GCP | ~$200/mo (smallest) | Disaggregated compute/storage | 99.99% |
| CockroachDB Serverless | CockroachDB | Cockroach Labs | Free (50M RU/mo) | Multi-AZ by default | 99.95% |
| CockroachDB Dedicated | CockroachDB | Cockroach Labs | ~$130/mo (2 vCPU) | Multi-AZ / multi-region | 99.99-99.999% |
| PlanetScale | MySQL (Vitess) | PlanetScale | Free / $5/mo | 3 nodes across AZs | 99.99% |
| Azure Database | PG / MySQL | Azure | ~$13/mo (Burstable) | Zone-redundant HA | 99.99% |
| Neon | PostgreSQL | Neon | Free (0.5 GiB) | Serverless, auto-scale | 99.95% |
| Supabase | PostgreSQL | Supabase | Free (500 MB) | Single-node (Pro: HA) | 99.9% (Pro) |
Key Differentiators¶
| Capability | RDS | Aurora | Cloud SQL | AlloyDB | CockroachDB Cloud | PlanetScale |
|---|---|---|---|---|---|---|
| Serverless | No | Yes (v2) | No | No | Yes (Basic plan) | No |
| Multi-region active-active | No | DSQL (preview) | No | No | Yes (native) | No |
| Online DDL | Engine-dependent | Engine-dependent | Engine-dependent | Yes | Yes (zero-downtime) | Yes (non-blocking) |
| Branching | No | No | No | No | No | Yes |
| Storage pricing | ~$0.12/GB-mo | ~$0.10/GB-mo | ~$0.17/GB-mo | ~$0.50/GB-mo | ~$1.00/GB-mo | ~$2.50/GB-mo |
Storage costs vary dramatically
CockroachDB and PlanetScale charge 5-25x more per GB than traditional managed services. This is offset by their distributed HA (no separate standby costs) and operational simplicity, but can be surprising at multi-TB scale.
Total Cost of Ownership¶
Licensing¶
| Database | License | Commercial Restrictions |
|---|---|---|
| PostgreSQL | PostgreSQL License (MIT-like) | None — fully permissive |
| MySQL | GPL 2.0 / Commercial (Oracle) | GPL copyleft for linked applications; commercial license available |
| CockroachDB | BSL 1.1 / CCL | Free for self-hosted production; cannot offer as a competing DBaaS |
Self-Hosted Cost Comparison (AWS, 3-year reserved)¶
| Scale | PostgreSQL | MySQL | CockroachDB |
|---|---|---|---|
| Small (2 vCPU, 8 GB, 100 GB) | ~$120/mo (1 primary + 1 standby) | ~$120/mo (1 primary + 1 replica) | ~$360/mo (3-node cluster minimum) |
| Medium (8 vCPU, 32 GB, 1 TB) | ~$600/mo (1 primary + 2 standbys) | ~$600/mo (1 primary + 2 replicas) | ~$1,200/mo (3-node cluster) |
| Large (32 vCPU, 128 GB, 10 TB) | ~$3,000/mo (1 primary + 3 standbys) | ~$3,000/mo (1 primary + 3 replicas) | ~$4,500/mo (5-node cluster) |
Operational Overhead¶
| Dimension | PostgreSQL | MySQL | CockroachDB |
|---|---|---|---|
| DBA skill availability | High (large talent pool) | High (largest talent pool) | Low (specialized skill) |
| Failover management | Manual or Patroni/pg_auto_failover | MySQL Router / ProxySQL | Automatic (built-in) |
| Backup tooling | pg_dump, pgBackRest, Barman | mysqldump, Percona XtraBackup | Built-in backup to cloud storage |
| Monitoring | pg_stat_*, pgBadger, Datadog | Performance Schema, PMM, Datadog | DB Console (built-in), Datadog |
| Schema migrations | Flyway, Alembic, golang-migrate | Flyway, Liquibase, gh-ost | Flyway, MOLT SCT |
| Estimated DBA FTE | 0.25-0.5 per cluster | 0.25-0.5 per cluster | 0.1-0.25 per cluster |
CockroachDB trades higher infra cost for lower ops cost
CockroachDB requires ~3x the compute for a minimal HA deployment, but eliminates the need for external failover tools, connection poolers, and manual shard management. At scale, the operational savings often exceed the infrastructure premium — especially for globally distributed applications.
Decision Framework by Annual Budget¶
| Budget | Recommended Path |
|---|---|
| < $5K/yr | PostgreSQL or MySQL on a single VPS + automated backups |
| $5K-25K/yr | Managed PostgreSQL (RDS, Cloud SQL, Neon) or managed MySQL (RDS, PlanetScale) |
| $25K-100K/yr | Aurora PostgreSQL or AlloyDB for performance; CockroachDB Serverless for distribution |
| $100K+/yr | CockroachDB Dedicated for global active-active; Aurora DSQL for AWS-native multi-region |
Sources¶
- PostgreSQL Documentation
- MySQL Documentation
- CockroachDB Documentation
- MySQL GitHub
- CockroachDB GitHub
- PostgreSQL Streaming Replication
- MySQL Group Replication Architecture
- CockroachDB Architecture Overview
- CockroachDB MOLT Migration Tools
- pgLoader Migration Guide (Percona)
- AWS DMS with CockroachDB
- Managed Postgres Providers Compared (2026)
- Aurora vs PlanetScale Pricing (Vantage)