FoundationDB, CockroachDB or TiDB?
| Dimension | FoundationDB | CockroachDB | TiDB |
|---|---|---|---|
| In one line | A distributed, ordered key-value store with strictly serializable transactions, meant as a base for other databases | A distributed SQL database that speaks the PostgreSQL wire protocol, with every node doing everything | A distributed SQL database that speaks the MySQL protocol, split into SQL, storage and coordination services |
| What you talk to | Client libraries (C, Python, Java, Go and others) that read and write keys inside transactions; no query language, schema or secondary indexes in the core | SQL from psql and PostgreSQL drivers and ORMs, through any node | SQL from MySQL clients, drivers and ORMs, through stateless TiDB servers behind a load balancer |
| SQL | Only through layers, such as the FoundationDB Record Layer’s SQL interface over JDBC | PostgreSQL-compatible, with gaps: no range types, foreign data wrappers or column-level privileges | Compatible with common MySQL 5.7 and 8.0 syntax, but no stored procedures, triggers, events or user-defined functions |
| How the cluster is built | Separate roles: coordinators, a cluster controller, a sequencer, proxies, resolvers, transaction logs and storage servers, scaled independently | One cockroach binary per node; each node runs the SQL layer and stores replicas of some ranges | TiDB servers for SQL, Placement Driver (PD) for metadata and timestamps, TiKV for row storage, optional TiFlash for columns |
| Replication | Commits are fsynced by the transaction logs, then pulled by storage servers; on failure the cluster recruits a new transaction system rather than voting | Raft per range of up to 512 MiB, three replicas by default; a leaseholder serves reads and coordinates writes | Raft per Region of 256 MiB by default in TiKV, three replicas; TiFlash copies data as asynchronous Raft learners |
| Ordering transactions | A single sequencer hands out read and commit versions | Hybrid logical clocks over NTP; a node whose clock drifts past the maximum offset (500 ms) shuts itself down | A central timestamp oracle (TSO) in PD: a physical millisecond time plus a logical counter, per transaction |
| Concurrency control | Optimistic: resolvers check the read set at commit, and a conflicting transaction fails with not_committed and is retried by the client | MVCC with serializable checks; conflicts surface as retry errors (SQLSTATE 40001) the application must handle, unless the transaction arrives as one batch | MVCC with a Percolator-style two-phase commit; pessimistic locking by default since v3.0.8, optimistic mode available |
| Default isolation | Strict serializability for every transaction | SERIALIZABLE; READ COMMITTED since 23.2 | Snapshot isolation, reported as REPEATABLE READ, which allows write skew; READ COMMITTED in pessimistic mode |
| Analytics | None built in; range reads over ordered keys | Row store; changefeeds stream changes to Kafka, Pub/Sub, cloud storage or webhooks for analysis elsewhere | TiFlash column replicas answer analytical queries on the same data, with snapshot-consistent reads |
| Hard limits and gotchas | Transactions last at most 5 seconds and touch at most 10 MB; keys up to 10 KB, values up to 100 KB; no access control | Retry loops for 40001; cross-region writes pay quorum round trips; licence key and telemetry needed for free production use | Transactions up to 100 MB by default (configurable to 1 TB) and rows up to 6 MiB; every transaction asks PD for timestamps; no spatial indexes and limited FULLTEXT |
| Licence | Apache 2.0, maintained by Apple | Proprietary CockroachDB Software License since v24.3 (November 2024); free Enterprise for businesses under $10 million revenue | Apache 2.0, maintained by PingCAP |
Rule of thumb
These sit at different levels. FoundationDB is the transactional engine you build a database on, as Apple and Snowflake did; pick it only if you’re writing that layer yourself and can live with 5-second transactions. Between the two SQL databases, start from the protocol your applications already speak: TiDB for MySQL, CockroachDB for PostgreSQL. CockroachDB gives serializable isolation by default and runs as one binary that is easy to spread across regions, but it is no longer open source. TiDB is Apache 2.0, separates SQL, storage and analytics so each can scale on its own, and adds column replicas for reporting, at the cost of more components to run and weaker default isolation.
Sources
- FoundationDB docs: Architecture (roles, read versions, commit path)
- FoundationDB docs: Consistency (strict serializability)
- FoundationDB docs: Known limitations
- FoundationDB docs: Layer concept
- Zhou et al.: FoundationDB, A Distributed Unbundled Transactional Key Value Store (SIGMOD 2021)
- FoundationDB Record Layer on GitHub (SQL over JDBC)
- apple/foundationdb on GitHub (Apache 2.0)
- CockroachDB docs: Architecture overview
- CockroachDB docs: Replication zones (512 MiB ranges)
- CockroachDB docs: `cockroach start` (maximum clock offset)
- CockroachDB docs: Transaction retry error reference
- CockroachDB docs: Read committed isolation
- CockroachDB docs: PostgreSQL compatibility
- CockroachDB docs: Changefeed sinks
- CockroachDB docs: Licensing FAQs
- TiDB docs: TiDB architecture
- TiDB docs: TiDB storage (Raft, 256 MiB Regions, MVCC, Percolator)
- TiDB docs: TimeStamp Oracle (TSO)
- TiDB docs: Pessimistic transaction mode
- TiDB docs: Transaction isolation levels
- TiDB docs: MySQL compatibility
- TiDB docs: Transactions overview (100 MB default size limit, 1 TB maximum)
- TiDB docs: TiDB limitations (6 MiB rows)
- TiDB docs: TiFlash overview (Raft learners, snapshot-consistent reads)
- pingcap/tidb on GitHub (Apache 2.0)