Spanner (9.1), CockroachDB (9.2), and FoundationDB (9.3) each answer the geo-distributed consensus question with a bespoke API and data model. TiDB and YugabyteDB make a different, additional bet on top of the same underlying Raft-based foundations: wire compatibility with an existing, enormously popular database — MySQL for TiDB, PostgreSQL for YugabyteDB — so that an application can gain distributed, Raft-backed strong consistency without rewriting its data-access layer at all. This article covers both systems' storage/compute separation, how Raft (5.5-5.6) gets applied per data range in each, and why "be a drop-in replacement for something already popular" is itself a legitimate, distinct architectural strategy worth naming alongside the purely technical design axes this series has covered so far.
Where both projects came from
Both systems emerged from the same broad moment in database history — the years immediately following Spanner's 2012 publication (article 9.1), when it became clear that "horizontally scalable, strongly consistent, SQL-speaking" was no longer a contradiction in terms, just a very hard engineering problem that Google had shown was solvable. PingCAP, the company behind TiDB, was founded in China in 2015 specifically to build an open-source system inspired by Spanner and by Google's earlier internal storage systems, targeting the enormous existing base of MySQL deployments as its adoption path. Yugabyte, the company behind YugabyteDB, was founded around the same period by engineers with backgrounds at Facebook and other large-scale infrastructure teams, targeting PostgreSQL specifically because of its broader extensibility and its growing popularity as the default choice for new application development. Neither company invented the underlying idea — Spanner (9.1) and F1, Google's SQL layer built on top of it, had already demonstrated the architecture was viable — but both made the specific, deliberate bet that the biggest adoption barrier for anyone else building a similar system wouldn't be the underlying consensus and storage engineering (hard, but by 2015 reasonably well understood, thanks to Raft's 2014 publication making this series' Phase 5 material broadly accessible) — it would be asking every prospective user to rewrite their application against a brand-new API.
Wire compatibility as a design goal, not an afterthought
Every system covered in Phase 9 so far required an application to speak that system's own specific API or query language — Spanner's own client libraries and SQL dialect, CockroachDB's PostgreSQL-inspired but not fully compatible SQL, FoundationDB's minimal key-value operations. TiDB and YugabyteDB both start from a different premise: rather than asking developers to adopt a new interface, present the exact same wire protocol and SQL dialect as an already-massively-deployed database (MySQL for TiDB, PostgreSQL for YugabyteDB), so that existing applications, existing drivers, and existing operational tooling continue to work largely unchanged, while the actual storage and consensus underneath is completely re-engineered for horizontal scale and strong consistency.
This is worth treating as a genuine, first-class architectural decision, not merely a marketing convenience. It creates a real engineering constraint that none of the other systems in Phase 9 had to satisfy: every SQL feature, every transaction-isolation nuance, every wire-protocol quirk of the original database has to be faithfully reproduced on top of a fundamentally different storage and consensus layer underneath. That constraint shapes the rest of both systems' architecture in ways worth tracing through directly.
TiDB: separating SQL compute from Raft-backed storage
TiDB's architecture splits cleanly into two independently-scalable tiers, a separation directly reminiscent of article 7.4's Compartmentalized Paxos discussion, just realized as a full production system rather than a research proposal. The TiDB server tier is a stateless SQL layer — it parses and plans queries, and speaks the MySQL wire protocol, but holds no data of its own and no consensus responsibility whatsoever. The actual data lives in TiKV, a separate, horizontally-scalable distributed key-value store that TiDB's creators (PingCAP) built specifically as TiDB's storage foundation, directly inspired by Google's internal storage systems that predate and informed Spanner's own design.
TiKV shards data into Regions — the same conceptual unit as CockroachDB's ranges (article 9.2) under a different name — each independently replicated by its own Raft group. A Region splits automatically as it grows past a size threshold, and TiKV's placement driver (a separate coordination component, itself Raft-backed for its own fault tolerance) continuously rebalances Region replicas across the cluster to keep load even — the same fundamental sharding-plus-rebalancing pattern this series has now seen three times (Spanner's shards, CockroachDB's ranges, TiKV's Regions), each time with slightly different terminology but the identical underlying majority-overlap safety mechanism (article 3.3) doing the actual correctness work underneath.
Fig 1 — SQL parsing/planning and Raft-backed storage scale independently, each tier sized for its own bottleneck.
YugabyteDB: DocDB underneath a PostgreSQL-compatible layer
YugabyteDB follows a structurally parallel design, aimed at PostgreSQL compatibility instead of MySQL's. Its storage engine, DocDB, is built directly on top of RocksDB (an embedded, single-node key-value storage library originally developed at Facebook) with a Raft-based replication layer added on top, sharding data into tablets — YugabyteDB's own name for the same underlying concept as TiKV's Regions and CockroachDB's ranges. YugabyteDB's SQL layer, called YSQL, is built to be close enough to genuine PostgreSQL that it reuses a substantial part of PostgreSQL's own upstream query-processing code, a deliberate choice to maximize actual compatibility (not just superficial syntax similarity) with the real PostgreSQL ecosystem — extensions, drivers, and tooling that assume real PostgreSQL semantics.
The consistent pattern across TiDB and YugabyteDB, worth stating explicitly because it's the actual lesson of this article: both systems separately, independently arrived at the same three-part formula — (1) shard data into small, independently-Raft-replicated units, (2) separate stateless query/compute logic from stateful storage/consensus logic, and (3) present a wire-compatible surface to an existing, popular database rather than inventing a new one. Given article 5.7's closing observation that Paxos, VR, Raft, and Zab converged independently on the same majority-overlap safety mechanism, this is a second, higher-level instance of the same kind of convergence — different teams, different starting points, arriving at structurally similar answers to "how do you build a horizontally-scalable, strongly-consistent SQL database" once Raft (5.5-5.6) is available as a solid, well-understood building block.
| System | Wire compatibility target | Storage engine | Sharding unit |
|---|---|---|---|
| TiDB | MySQL | TiKV (custom, Raft-backed) | Region |
| YugabyteDB | PostgreSQL | DocDB (built on RocksDB) | Tablet |
| CockroachDB (9.2, for contrast) | PostgreSQL-inspired, not fully wire-compatible | Custom, built on Pebble/RocksDB-family | Range |
Raft mechanics at the Region/tablet level, concretely
It's worth tracing what actually happens, mechanically, when a client issues a write against a TiDB cluster, because it makes concrete exactly how much of this series' Phase 5 machinery is doing real, load-bearing work underneath a query that looks, from the application's point of view, like an ordinary MySQL statement. The stateless TiDB server tier parses the SQL statement and determines which Region (or Regions, for a multi-row write) the affected keys belong to, using metadata it maintains about the current Region-to-node mapping. It then forwards the write to that Region's current Raft leader — found via the same kind of leader-tracking this series covered in article 5.5, with the TiDB server retrying against a different replica if it guesses wrong about which node currently holds leadership, exactly the kind of transient misdirection article 5.5's stale-leader discussion anticipated. The Raft leader for that Region then runs the ordinary AppendEntries replication flow from article 5.6 — proposing the write to its followers, waiting for a majority to acknowledge, and only then considering the write committed and returning success up through the TiDB server tier back to the client. A single SQL statement touching several rows spread across different Regions may involve several such Raft rounds, coordinated by a two-phase-commit-style protocol at the TiDB server tier to keep the whole multi-Region write atomic — directly recalling article 4.4's 2PC discussion, here deployed deliberately, at a scale where the number of participants (the specific Regions touched) is usually small enough that 2PC's blocking risk is judged an acceptable trade against the complexity of an alternative.
YugabyteDB's DocDB tablets follow the structurally identical flow — a query touching a tablet is routed to that tablet's Raft leader, replicated via the same AppendEntries mechanism, and multi-tablet transactions coordinate via a comparable atomic-commit protocol at the YSQL layer. The point worth taking away from tracing this out explicitly: everything genuinely novel about TiDB and YugabyteDB, as products, lives in the SQL-compatibility layer and the sharding/rebalancing logic — the actual consensus doing the correctness work, at the bottom of the stack, is exactly the Raft machinery this series built from first principles across articles 5.5 and 5.6, unmodified.
Why not just use CockroachDB, if the underlying pattern is the same?
Given how structurally similar TiDB, YugabyteDB, and CockroachDB (9.2) all turn out to be once you look underneath the marketing surface — shard into small units, replicate each with Raft, separate compute from storage — it's worth asking directly why all three exist as separate, competing products rather than the field converging on one. The honest answer is that the wire-compatibility choice is not a minor implementation detail; it's close to the single most consequential decision each project made, and it's genuinely different across the three. CockroachDB deliberately chose to be PostgreSQL-inspired without committing to full wire compatibility, giving its team more freedom to diverge from PostgreSQL's exact behavior where doing so serves the distributed setting better, at the cost of not being a true drop-in replacement. YugabyteDB committed harder to genuine PostgreSQL compatibility, accepting the ongoing burden of tracking upstream PostgreSQL's evolution in exchange for a smoother migration story for the (very large) existing PostgreSQL user base. TiDB targeted MySQL specifically because of MySQL's own enormous, partially non-overlapping installed base, particularly strong in certain regions and industries. None of these are simply "more correct" than the others — they're different bets about which existing user base is worth optimizing the migration path for, made by different teams at different times with different market assumptions, which is precisely why this series treats the choice as a legitimate architectural axis in its own right rather than a footnote.
FAQ
Are TiDB and YugabyteDB actually 100% compatible with MySQL and PostgreSQL respectively?
Close, but not perfectly — both projects maintain public compatibility documentation listing specific unsupported features or behavioral differences, typically around certain advanced SQL features, specific isolation-level edge cases, or extensions that assume single-node storage internals. The compatibility bet is "close enough that most real applications migrate with minimal changes," not "byte-for-byte identical in every corner case."
Why would TiKV or DocDB be preferred over just using CockroachDB directly?
The choice mostly comes down to which existing database an organization is already running and wants to migrate from with minimal application changes — a team on MySQL has a smoother path to TiDB; a team on PostgreSQL has a smoother path to YugabyteDB or CockroachDB (which is PostgreSQL-inspired but not fully wire-compatible). This is a migration-cost decision more than a pure technical-superiority one, consistent with this article's core argument.
Does the stateless SQL tier in TiDB introduce any consensus concerns of its own?
No — this is precisely the point of the separation: the TiDB server tier holds no durable state and makes no consensus-relevant decisions itself, so it can be scaled up or down, or restarted, without any of the safety concerns this series has spent eight phases building (majority overlap, log replication, leader election). All of that machinery lives entirely within TiKV's per-Region Raft groups.
A brief note on TiDB's hybrid transactional/analytical angle
One further distinguishing feature worth naming, since it's a genuine architectural addition rather than just another wire-compatibility flavor: TiDB ships an optional columnar storage engine, TiFlash, that replicates the same underlying data from TiKV's row-oriented Regions into a column-oriented format specifically optimized for analytical queries, kept consistent with the primary row-store via the Raft log itself (TiFlash nodes act as a special kind of Raft learner, replaying the same committed log entries other Region replicas apply, just materializing them into a different physical storage layout). This lets a single TiDB cluster serve both ordinary transactional MySQL-style queries and large analytical scans against the same consistent data, without a separate ETL pipeline into a different analytics system — a real, distinctive engineering answer to the classic transactional-versus-analytical workload split, built directly on top of the same Raft replication mechanism this article has traced throughout, rather than requiring an entirely separate consensus or replication story for the analytical path.
Takeaways
- TiDB (MySQL-compatible) and YugabyteDB (PostgreSQL-compatible) both bet on wire compatibility with an already-popular database as a first-class architectural goal, not an afterthought — minimizing application migration cost.
- Both separate a stateless SQL/compute tier from a sharded, Raft-backed storage tier — TiKV's Regions, YugabyteDB's DocDB tablets — the same fundamental pattern as CockroachDB's ranges, under different names.
- Both independently converged on the same three-part formula (shard + separate compute/storage + wire-compatible surface) once Raft (5.5-5.6) was available as a solid foundation — a second-order instance of the convergence article 5.7 first identified among the classical algorithms themselves.
- Wire compatibility is a genuine, distinct trade-off axis — a migration-cost bet, not a safety/liveness or latency/throughput one — with its own ongoing engineering burden (faithfully tracking an evolving upstream database's behavior).
References & further reading
- PingCAP — TiDB Architecture — the TiDB server / TiKV separation described directly.
- YugabyteDB documentation — Architecture — DocDB, tablets, and the YSQL compatibility layer.
- cvam.sight — Consensus 9.2: CockroachDB and Multi-Raft — the closely parallel per-range Raft sharding pattern.