Skip to content

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 + 1 members to tolerate f failures. 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_leader for 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:

  • ENUM types map differently (MySQL ENUM to PG ENUM or VARCHAR)
  • AUTO_INCREMENT maps to SERIAL / IDENTITY
  • MySQL's TINYINT(1) for booleans needs mapping to PG BOOLEAN
  • 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)
  • SERIAL columns should be converted to UUID for 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:

  1. MySQL to PostgreSQL (via pgLoader or DMS)
  2. 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

See Also