# Distributed SQL Benchmarks: CockroachDB vs. YugabyteDB vs. TiDB Architecture & Latency in Production
Summary: Distributed SQL engines eliminate manual application-level sharding while preserving ACID transactions, but their divergent internals impose distinct operational trade-offs. CockroachDB implements a single-binary Go and Pebble architecture prioritizing Multi-Raft survivability and strict Serializable isolation. YugabyteDB combines a PostgreSQL query layer with a C++ RocksDB-based DocDB storage engine for sub-millisecond local reads and PostgreSQL feature parity. TiDB decouples compute from Rust-based TiKV and columnar TiFlash storage, excelling at high-throughput transactions and real-time hybrid transactional and analytical processing (HTAP).
---
1. Architectural Foundations: Multi-Raft, Query Engines, and Storage Subsystems
Evaluating distributed SQL benchmarks across CockroachDB, YugabyteDB, and TiDB requires examining the fundamental architectural trade-offs separating each engine. Modern distributed relational database management systems (NewSQL) solve horizontal scale through two core mechanisms: breaking monotonic write logs into independent consensus groups (Multi-Raft) and decoupling relational query parsing from transactional key-value storage. However, their structural implementations diverge across language runtimes, storage engines, and transaction protocols.
+---------------------------------------------------------------------------------------------------+
| DISTRIBUTED SQL QUERY ENGINES |
+---------------------------------+---------------------------------+-------------------------------+
| CockroachDB | YugabyteDB | TiDB |
| Single-Binary Engine (Go) | Forked PostgreSQL (C) | Stateless SQL Layer (Go) |
| Vectorized Execution | Native PL/pgSQL & Extensions | MySQL Protocol & Planner |
+---------------------------------+---------------------------------+-------------------------------+
| DISTRIBUTED CONSENSUS LAYER |
+---------------------------------+---------------------------------+-------------------------------+
| Multi-Raft Range Groups | Multi-Raft Tablet Groups | Multi-Raft Region Groups |
| Range Leases + HLC | Leader Leases + HLC | Percolator 2PC + Central TSO |
+---------------------------------+---------------------------------+-------------------------------+
| STORAGE SUBSYSTEMS |
+---------------------------------+---------------------------------+-------------------------------+
| Pebble (Go LSM-Tree) | DocDB (C++ Custom RocksDB) | TiKV (Rust RocksDB) & |
| Zero CGo overhead | Document-level MVCC | TiFlash (C++ Columnar HTAP) |
+---------------------------------+---------------------------------+-------------------------------+CockroachDB: Single-Binary Go Runtime, Vectorized SQL, and the Pebble LSM Engine
CockroachDB uses a symmetric, single-binary architectural model written in Go. Every deployed node runs identical software and can act simultaneously as a SQL execution coordinator, a Raft consensus participant, and a leaseholder for underlying data ranges.
The query pipeline parses PostgreSQL-dialect SQL into an abstract syntax tree (AST), optimizes execution paths using a cost-based optimizer (CBO) built in Go, and evaluates queries via a vectorized execution engine. This vectorized engine operates directly on columnar memory batches (typically 1,024 tuple vectors) rather than standard row-at-a-time iterator models (Volcano iterator), cutting CPU instruction overhead and memory allocations.
Below the query engine sits Pebble, an LSM-tree (Log-Structured Merge-tree) storage engine written natively in Go. CockroachDB originally relied on C++ RocksDB via CGo. Under high-throughput workloads, cross-boundary CGo context switches introduced measurable latency, memory allocation contention, and non-deterministic Go runtime garbage collector pause interactions. Pebble eliminated the CGo boundary entirely, providing direct memory coordination with Go's garbage collector, customized block-cache eviction, and optimized SSTable compactions tuned specifically for CockroachDB's Multi-Raft keyspace.
The keyspace is organized as a single, contiguous, sorted key-value space partitioned into dynamic 512MB Ranges (the default range_max_bytes in modern CockroachDB releases such as v24.2, increased from legacy 64MB defaults to reduce metadata indexing overhead and scale storage capacity per node). Each Range forms an independent Raft consensus group across cluster nodes. CockroachDB separates Raft leadership from read authorization through Range Leases:
1. The Leaseholder replica serves all consistent reads directly without executing a Raft quorum round-trip.
2. The Leaseholder coordinates writes by proposing changes to the Raft group, collecting a quorum of acknowledgments, and committing the transaction record.
YugabyteDB: Forked PostgreSQL Query Layer and DocDB (C++ RocksDB)
YugabyteDB takes an alternate architectural path: reusing standard PostgreSQL relational internals directly while replacing PostgreSQL's storage and execution subsystem with a distributed storage tier. The architecture consists of two daemon processes:
- `yb-master`: Coordinates cluster metadata, tablet distribution, schema definitions, and placement policies via an internal Raft consensus group.
- `yb-tserver` (Tablet Server): Accepts client SQL connections, executes query plans, and manages local data partitions.
YugabyteDB's SQL layer (YSQL) incorporates the actual C runtime, parser, and planner of PostgreSQL. Historically built on PostgreSQL 11.2 compatibility in the 2.x and v2024.1 release train, YugabyteDB introduced a PostgreSQL 15 rebase in preview in v2.25, reaching production general availability in v2025.1. Because YSQL reuses upstream PostgreSQL source code, it provides high feature parity with PostgreSQL capabilities, including stored procedures, triggers, custom types, extensions (pg_trgm, PostGIS, uuid-ossp), and advanced window functions that other NewSQL engines must re-engineer from scratch.
Beneath YSQL runs DocDB, a distributed storage engine written in C++. DocDB is built on a heavily modified fork of RocksDB. Tables are divided into Tablets using either consistent hash partitioning (for uniform write distributions) or range partitioning (for efficient sequential scans). Each Tablet constitutes an independent Raft consensus group.
DocDB modifies standard RocksDB key-value semantics to support semi-structured documents:
- Relational table rows are mapped to multiple DocDB key-value entries where individual column updates do not require rewriting the full row.
- Multi-Version Concurrency Control (MVCC) timestamps based on Hybrid Logical Clocks (HLC) are embedded directly within RocksDB keys, allowing DocDB to purge stale records during background LSM compactions without requiring explicit transactional VACUUM operations.
- Tablet leader leases guarantee that reads served from the local leader node are strictly linearizable without invoking Raft consensus on every SELECT query.
TiDB: Disaggregated Compute-Storage Architecture with TiKV and TiFlash HTAP
TiDB, authored by PingCAP, isolates compute and storage into decoupled, independently scalable clusters. Instead of running single-binary nodes or coupling query runtimes with local storage engines, TiDB decomposes database responsibilities into three distributed systems:
1. TiDB Server (Stateless Compute Layer): Written in Go, TiDB nodes act as stateless SQL gateways implementing the MySQL wire protocol. TiDB receives SQL queries, performs cost-based optimization, handles joins and aggregations, and generates distributed execution plans. Because these servers maintain no local transactional data, compute capacity scales out instantly behind a Layer-4 or Layer-7 load balancer.
2. Placement Driver (PD): Written in Go and backed by etcd's Raft consensus implementation, PD acts as the cluster brain. PD issues globally monotonic transaction timestamps via its centralized Timestamp Oracle (TSO), tracks topology changes, and dynamically instructs storage nodes to split, merge, or rebalance partitions.
3. TiKV (Distributed Transactional Storage Engine): Written in Rust, TiKV provides a transactional key-value store organized into 96MB Regions. Each Region replicates data across TiKV instances using Multi-Raft. Within each TiKV node, storage is handled by two internal RocksDB instances: one for the Raft consensus log, and one for user data and MVCC records. TiKV executes distributed transactional operations using Google's Percolator two-phase commit protocol.
4. TiFlash (Columnar HTAP Engine): Written in C++, TiFlash provides a dedicated columnar storage engine for analytical execution. TiFlash nodes participate in the TiKV Raft groups as Raft Learner nodes (non-voting replicas). TiFlash receives continuous, asynchronous write streams from TiKV without imposing write penalties on the OLTP Raft quorum. The TiDB optimizer automatically routes analytical queries to TiFlash and point lookups to TiKV.
---
2. Distributed Storage & Consensus Topology Comparison
To understand how each engine coordinates read and write paths across network boundaries, the diagram below compares client request flows, consensus coordination, and underlying storage layouts across CockroachDB, YugabyteDB, and TiDB.
flowchart TD
subgraph CRDB["CockroachDB (Unified Single Binary - Go)"]
C_Client["Client (Postgres Driver)"] --> C_Node1["CockroachDB Node (Gateway)"]
C_Node1 --> C_Plan["Vectorized Query Engine"]
C_Plan --> C_Lease["Range Leaseholder"]
C_Lease -->|Multi-Raft Consensus| C_R1["Replica 1 (Leader)"]
C_Lease -->|Parallel Commit| C_R2["Replica 2"]
C_Lease -->|Async Log| C_R3["Replica 3"]
C_R1 --> C_Pebble["Pebble LSM Engine (Go)"]
end
subgraph YB["YugabyteDB (Dual-Daemon - C/C++)"]
Y_Client["Client (Postgres Driver)"] --> Y_TS["YB-TServer (YSQL C Layer)"]
Y_Master["YB-Master Cluster (Metadata Raft)"] -.->|Topology / Catalog| Y_TS
Y_TS --> Y_DocDB["DocDB Query Translation"]
Y_DocDB -->|Multi-Raft Consensus| Y_TL["Tablet Leader"]
Y_TL -->|Raft Log Replication| Y_TF1["Tablet Follower 1"]
Y_TL -->|Raft Log Replication| Y_TF2["Tablet Follower 2"]
Y_TL --> Y_Rocks["DocDB Custom RocksDB (C++)"]
end
subgraph TIDB["TiDB (Disaggregated HTAP - Go / Rust / C++)"]
T_Client["Client (MySQL Driver)"] --> T_Compute["Stateless TiDB Server (Go)"]
T_PD["Placement Driver (PD / TSO)"] <-->|Allocate Timestamps| T_Compute
T_Compute -->|Coprocessor Pushdown| T_TiKV["TiKV Node (Rust OLTP)"]
T_Compute -->|MPP Vector Pushdown| T_TiFlash["TiFlash Node (C++ OLAP)"]
T_TiKV -->|Multi-Raft Leader| T_R1["TiKV Leader (RocksDB)"]
T_TiKV -->|Multi-Raft Follower| T_R2["TiKV Follower (RocksDB)"]
T_R1 -.->|Raft Learner Replication| T_TiFlash
endThe fundamental contrast lies in coordination overhead:
- CockroachDB combines SQL processing, consensus coordination, and storage in a single process. Any node coordinates transactions. Parallel Commits optimize write paths to a single Raft round-trip by allowing the transaction coordinator to return success once write intents and the transaction record staging status are committed concurrently across the Raft quorum.
- YugabyteDB coordinates execution directly within the
yb-tserverprocess, converting PostgreSQL tuples into DocDB key paths. By executing write-intents and Raft proposals within native C++, it achieves minimal memory copying and near-zero serialization overhead between the query layer and RocksDB storage. - TiDB decouples the query coordinator (TiDB Server) from the storage engine (TiKV) via gRPC Coprocessor connections. Every transactional write must fetch a global timestamp from PD, establish locks across TiKV regions using Percolator two-phase commits, and commit data via independent Raft groups. While this introduces an additional network hop, it allows compute and storage tiers to autoscale independently.
---
3. TPC-C Benchmark Performance: Throughput and P99 Tail Latency Analysis
Evaluating operational throughput and latency trade-offs across distributed SQL engines requires examining standardized workload profiles under controlled network topologies. In multi-node distributed database research, performance profiles are benchmarked using the standard TPC-C workload profile (45% NewOrder, 43% Payment, 4% OrderStatus, 4% Delivery, 4% StockLevel) executed via open-source frameworks such as OLTP-Bench or vendor-maintained TPC-C test harnesses.
The metrics presented below synthesize normalized comparative reference figures derived from published empirical multi-node studies—including the Cockroach Labs Cloud Report, PingCAP Official TiDB TPC-C Benchmarks, and YugabyteDB Performance Whitepapers—modeled across 2,500 warehouses under 500 concurrent client threads to illustrate relative engine scaling under latency injection.
Test Topology and Workload Parameters
To ensure meaningful cross-engine comparison, reference configurations are evaluated on identical hardware baselines across three Amazon Web Services (AWS) deployment topologies:
- Nodes: 9 database nodes total (3 nodes per failure zone or region).
- EC2 Instance Type:
i4i.4xlarge(16 vCPUs, 128 GiB RAM, 1x 3.75 TB AWS Nitro SSD NVMe drive). - Storage Configuration: Local NVMe drives formatted with XFS, direct I/O enabled, WAL and data files hosted on isolated directories.
- OS / Kernel Tuning: Amazon Linux 2023, kernel 6.1,
transparent_hugepage=madvise,sysctl -w vm.dirty_ratio=10,vm.dirty_background_ratio=5. - Database Engine Versions: CockroachDB v24.2, YugabyteDB v2.21 / v2024.1, TiDB v7.5.
+---------------------------------------------------------------------------------------------------+
| Network Latency Simulation Profiles: |
| 1. Single-Region / Intra-AZ: Native AWS sub-millisecond local network baseline (<1.0ms RTT). |
| 2. Multi-AZ / High-Latency Metro Simulation: Synthetic 15ms round-trip network RTT injected via |
| Linux tc-netem (simulating degraded cross-zone routing or geographically distant metro pairs). |
| 3. Cross-Continental Multi-Region Simulation: Synthetic 65ms average round-trip network RTT |
| between three cloud regions (us-east-1, us-west-2, eu-central-1). |
+---------------------------------------------------------------------------------------------------+Benchmark Performance Results
The following table summarizes normalized sustained TPC-C throughput (tpmC) and P99 tail latency metrics synthesized from published multi-node evaluation suites and standardized network injection testbeds:
| Database Engine | Network Environment | TPC-C Throughput (tpmC) | P50 Read Latency | P99 Read Latency | P50 Write Latency | P99 Write Latency | Abort / Retry Rate |
|---|---|---|---|---|---|---|---|
| YugabyteDB v2.21 | Single-Region (Local NVMe, ~1ms RTT) | 212,400 | 1.1 ms | 3.8 ms | 4.2 ms | 9.8 ms | 0.04% |
| CockroachDB v24.2 | Single-Region (Local NVMe, ~1ms RTT) | 198,600 | 1.4 ms | 4.2 ms | 5.1 ms | 14.1 ms | 0.85% |
| TiDB v7.5 | Single-Region (Local NVMe, ~1ms RTT) | 184,200 | 1.8 ms | 5.9 ms | 6.4 ms | 12.6 ms | 0.12% |
| CockroachDB v24.2 | Multi-AZ (Simulated 15ms Inter-AZ RTT) | 154,100 | 2.4 ms | 7.9 ms | 17.8 ms | 41.2 ms | 1.94% |
| YugabyteDB v2.21 | Multi-AZ (Simulated 15ms Inter-AZ RTT) | 148,500 | 2.2 ms | 8.4 ms | 18.2 ms | 38.6 ms | 0.42% |
| TiDB v7.5 | Multi-AZ (Simulated 15ms Inter-AZ RTT) | 129,300 | 3.1 ms | 11.2 ms | 22.4 ms | 54.8 ms | 0.68% |
| CockroachDB v24.2 | Cross-Region (Simulated 65ms Inter-Region RTT) | 89,400 | 2.8 ms (Local) | 12.1 ms | 88.5 ms | 148.0 ms | 4.82% |
| YugabyteDB v2.21 | Cross-Region (Simulated 65ms Inter-Region RTT) | 83,100 | 2.6 ms (Local) | 14.8 ms | 94.2 ms | 162.4 ms | 1.85% |
| TiDB v7.5 | Cross-Region (Simulated 65ms Inter-Region RTT) | 38,700 | 4.2 ms (Local) | 28.6 ms | 184.0 ms | 342.0 ms | 7.15% |
Note: Benchmark figures represent normalized reference values compiled from vendor-published evaluation reports and architectural test suites. Actual production throughput varies based on storage subsystem IOPs, network jitter, client connection concurrency, and schema key distribution.
Latency and Throughput Analysis
1. Single-Region Performance: YugabyteDB demonstrates the highest tpmC throughput (212,400) and lowest P99 write tail latency (9.8ms). YSQL's direct execution within the yb-tserver memory space, combined with DocDB's C++ storage engine and pessimistic row locking, eliminates cross-process serialization overhead. CockroachDB follows closely at 198,600 tpmC, where Pebble's Go implementation maintains predictable memory allocation. TiDB trails slightly at 184,200 tpmC due to the network boundary between the stateless TiDB SQL layer and TiKV storage nodes.
2. Multi-AZ Behavior: When inter-node network latency increases to 15ms, Raft quorum rounds dominate write latency. CockroachDB achieves 154,100 tpmC by utilizing its Parallel Commits protocol, which reduces the multi-partition commit barrier to a single consensus phase. YugabyteDB maintains 148,500 tpmC with a tighter P99 write latency (38.6ms vs 41.2ms). TiDB incurs additional overhead (54.8ms P99) because transaction coordinators must execute gRPC RPC calls to PD for TSO timestamps across AZ boundaries.
3. Cross-Continental Multi-Region Behavior: In the 65ms cross-region topology, CockroachDB and YugabyteDB apply geo-partitioning and table-locality constraints:
* CockroachDB's leaseholder placement rules keep read leases pinned to local regions, serving point lookups in under 3ms. Write operations that touch local ranges require a Raft consensus round-trip across two of the three regions, yielding 89,400 tpmC.
* YugabyteDB's tablespace mapping achieves 83,100 tpmC with 162.4ms P99 write latency.
* TiDB encounters a critical bottleneck in cross-region topologies: the centralized Placement Driver TSO. Because every transaction must synchronize physical-logical timestamps against the active PD leader, cross-region network latency inflates both read and write coordination, dropping throughput to 38,700 tpmC and inflating P99 write tail latency to 342.0ms. TiDB is fundamentally designed for low-latency metropolitan or single-region deployments rather than cross-continental active-active configurations.
---
4. Isolation Levels and the Anatomy of a Transaction Retry Storm
A critical operational divergence among distributed SQL engines is default transaction isolation: Serializable Snapshot Isolation (SSI) in CockroachDB versus Snapshot Isolation (SI) in YugabyteDB and TiDB.
When our distributed systems engineers at Wise Hustlers Custom Software design mission-critical transactional platforms, database selection comes down to balancing cross-AZ consensus latency against workload concurrency and write contention patterns. Underestimating how an engine handles concurrent conflicting writes frequently leads to catastrophic cluster degradation.
Serializable Snapshot Isolation (SSI) vs. Snapshot Isolation (SI)
+---------------------------------------------------------------------------------------------------+
| ISOLATION LEVEL COMPARISON |
+--------------------------+-------------------------------------+----------------------------------+
| Feature | Serializable Snapshot Isolation | Snapshot Isolation (SI) |
| | (CockroachDB Default) | (YugabyteDB / TiDB Default) |
+--------------------------+-------------------------------------+----------------------------------+
| Write Skew Anomalies | Prohibited (Guaranteed Serial) | Permitted |
| Read-Write Conflicts | Aborts with SQLSTATE 40001 | Readers never block or abort |
| Write-Write Conflicts | Aborts or Pushes Timestamp | First committer wins / Lock wait |
| Concurrency Control | Optimistic + Read-Write Trackers | Pessimistic / Lock Waiters |
| Throughput Under Skew | Severe collapse under contention | Predictable, bounded degradation |
+--------------------------+-------------------------------------+----------------------------------+- Snapshot Isolation (SI) guarantees that all reads within a transaction observe a consistent snapshot of the database taken at transaction start time. SI prevents dirty reads, non-repeatable reads, and phantom reads. However, SI permits write skew anomalies (e.g., two concurrent transactions reading overlapping account balances and executing opposing debits that violate a global balance invariant).
- Serializable (SSI) guarantees that concurrent transactions yield the exact outcome as if executed strictly sequentially. CockroachDB tracks read and write memory footprints using transaction record intents and read-timestamp caches. If Transaction B writes to a key that Transaction A read earlier in its execution, an anti-dependency cycle is detected. To preserve serializability, the engine must abort Transaction A or push its read timestamp into the future.
The Mechanics of Raft-Level Contention and Cascading Retry Storms
When a high-concurrency transactional application targets contested records (such as an inventory decrement for a flash sale or ledger balance updates), strict serializable engines enter a failure state known as a Transaction Retry Storm:
sequenceDiagram
autonumber
participant App as Application Client
participant Node1 as Coordinator (Node 1)
participant Lease as Range Leaseholder
participant Raft as Raft Quorum Replicas
App->>Node1: BEGIN TRANSACTION (Serializable)
Node1->>Lease: SELECT balance FROM accounts WHERE id = 42
Lease-->>Node1: balance = 500 (Read Timestamp T1)
Note over Lease: Concurrent Tx 2 updates accounts (id=42) at T2
Lease->>Raft: Commit Tx 2 (Timestamp T2 > T1)
Raft-->>Lease: Quorum Confirmed
App->>Node1: UPDATE accounts SET balance = balance - 100 WHERE id = 42
Node1->>Lease: Write Intent (id=42, T1)
Note over Lease: Anti-dependency detected!<br/>Key modified after Read Timestamp T1
Lease-->>Node1: ERROR: TransactionRetryWithProtoRefreshError (40001)
Node1-->>App: ERROR: 40001 serialization_failure
Note over App: NAIVE RETRY LOOP (Immediate Retries)<br/>100 concurrent threads re-execute simultaneously
App->>Node1: BEGIN TRANSACTION (Immediate Retry)
Note over Node1,Raft: CPU spikes to 100% on coordinator threads.<br/>All cycles spent parsing aborted transactions.<br/>Cluster throughput collapses.In this scenario:
1. One hundred client threads attempt to update row id = 42 simultaneously.
2. Under CockroachDB's SSI, one transaction wins; the remaining 99 transactions fail with SQLSTATE 40001 (serialization_failure).
3. If client connection pools (e.g., HikariCP, Node-PG) catch 40001 and immediately re-execute without exponential backoff and jitter, they flood coordinators with duplicate work.
4. Coordinator CPUs saturate at 100% evaluating queries that are destined to abort, starving the cluster of resources to commit the winning transaction. Cluster throughput collapses from thousands of operations per second to single digits.
In contrast, YugabyteDB and TiDB default to Snapshot Isolation backed by pessimistic row locking (SELECT ... FOR UPDATE or automatic row locks). Conflicting transactions queue gracefully on row locks within DocDB or TiKV rather than immediately failing and aborting. Transactions experience higher P99 latency while waiting in lock queues, but aggregate cluster throughput remains stable without inducing retry storms.
---
5. Production Implementation: Resilient Client and Topology Configurations
Operating distributed SQL under high concurrency requires defensive client drivers and explicit database placement policies.
Resilient TypeScript Transaction Runner with Exponential Jitter
To prevent serialization retry storms under CockroachDB or YugabyteDB Serializable transactions, client applications must implement Decorrelated Jitter backoff algorithms. The following production-ready TypeScript implementation wraps PostgreSQL client operations in a resilient execution envelope:
import { Pool, PoolClient } from 'pg';
export interface RetryOptions {
maxRetries: number;
baseDelayMs: number;
maxDelayMs: number;
}
const DEFAULT_RETRY_OPTIONS: RetryOptions = {
maxRetries: 5,
baseDelayMs: 20,
maxDelayMs: 1500,
};
/**
* Calculates decorrelated jitter backoff delay.
* sleep = min(maxDelay, random(baseDelay, sleep * 3))
*/
function calculateDecorrelatedJitter(
currentDelay: number,
baseDelay: number,
maxDelay: number
): number {
const nextMax = Math.min(maxDelay, Math.max(baseDelay, currentDelay * 3));
return Math.floor(Math.random() * (nextMax - baseDelay + 1)) + baseDelay;
}
/**
* Executes a distributed SQL transaction with automatic retry handling
* for SQLSTATE 40001 (serialization_failure) and 40P01 (deadlock_detected).
*/
export async function runDistributedTransaction<T>(
pool: Pool,
operation: (client: PoolClient) => Promise<T>,
options: RetryOptions = DEFAULT_RETRY_OPTIONS
): Promise<T> {
let attempt = 0;
let currentDelay = options.baseDelayMs;
while (attempt <= options.maxRetries) {
const client = await pool.connect();
try {
await client.query('BEGIN TRANSACTION ISOLATION LEVEL SERIALIZABLE;');
const result = await operation(client);
await client.query('COMMIT;');
return result;
} catch (error: any) {
await client.query('ROLLBACK;').catch(() => {});
const isSerializationFailure = error?.code === '40001';
const isDeadlock = error?.code === '40P01';
if ((isSerializationFailure || isDeadlock) && attempt < options.maxRetries) {
attempt++;
currentDelay = calculateDecorrelatedJitter(
currentDelay,
options.baseDelayMs,
options.maxDelayMs
);
console.warn(
`[DistributedTx] Contention abort (code: ${error.code}). Retrying attempt ${attempt}/${options.maxRetries} after ${currentDelay}ms`
);
await new Promise((resolve) => setTimeout(resolve, currentDelay));
} else {
throw error;
}
} finally {
client.release();
}
}
throw new Error(`[DistributedTx] Exceeded maximum retry attempts (${options.maxRetries})`);
}CockroachDB Zone Configuration and Leaseholder Directives
To optimize multi-region deployments, CockroachDB administrators apply zone configurations that constrain replica counts and anchor leaseholders close to regional user bases:
-- Define multi-region database topology
ALTER DATABASE payments_ledger SET PRIMARY REGION "us-east-1";
ALTER DATABASE payments_ledger ADD REGION "us-west-2";
ALTER DATABASE payments_ledger ADD REGION "eu-central-1";
-- Configure local table survivability and leaseholder affinity
ALTER TABLE payments_ledger.transactions CONFIGURE ZONE USING
num_replicas = 3,
constraints = '{"+region=us-east-1": 1, "+region=us-west-2": 1, "+region=eu-central-1": 1}',
lease_preferences = '[[+region=us-east-1]]';YugabyteDB YB-TServer and Master Topology Flags
To eliminate cross-region read hops and ensure fault domain isolation, YugabyteDB nodes are initialized with explicit placement flags:
# YB-Master startup configuration with cloud placement awareness
./bin/yb-master \
--master_addresses=10.0.1.10:7100,10.0.2.10:7100,10.0.3.10:7100 \
--rpc_bind_addresses=10.0.1.10:7100 \
--placement_cloud=aws \
--placement_region=us-east-1 \
--placement_zone=us-east-1a \
--fs_data_dirs=/mnt/nvme0n1/data
# YB-TServer configuration enabling bounded-staleness follower reads
./bin/yb-tserver \
--tserver_master_addrs=10.0.1.10:7100,10.0.2.10:7100,10.0.3.10:7100 \
--rpc_bind_addresses=10.0.1.20:9100 \
--placement_cloud=aws \
--placement_region=us-east-1 \
--placement_zone=us-east-1a \
--ysql_enable_read_from_followers=true \
--leader_failure_max_missed_heartbeat_periods=6 \
--fs_data_dirs=/mnt/nvme0n1/dataTiDB Placement Driver (PD) Regional Rules
TiDB provides granular control over TiKV replica distribution using SQL-driven Placement Policies:
-- Establish regional placement policies in TiDB SQL
CREATE PLACEMENT POLICY us_east_primary
PRIMARY_REGION="us-east-1"
REGIONS="us-east-1,us-west-2,eu-central-1"
SCHEDULE="MAJORITY_IN_PRIMARY";
-- Bind transactional tables to localized placement policies
ALTER TABLE orders PLACEMENT POLICY=us_east_primary;
-- Inspect placement scheduling status via system tables
SELECT * FROM information_schema.placement_policies WHERE policy_name = 'us_east_primary';---
6. AWS 3-Region Deployment Infrastructure Cost Analysis (100,000 QPS)
A critical factor for tech leads and engineering directors is the Total Cost of Ownership (TCO) required to sustain a high-throughput transactional workload. The following monthly Bill of Materials (BOM) provides an architectural infrastructure sizing model derived from published AWS On-Demand EC2 pricing schedules and AWS Pricing Calculator guidelines for sizing high-concurrency 100,000 QPS deployments. This model serves as an architectural planning baseline for comparing resource footprints, rather than an empirical audit of customer production telemetry.
Workload Dimensioning and Hardware Sizing
- Target Throughput: 100,000 queries per second (80% point reads, 20% transactional writes).
- Working Set Storage: 15 TB active transactional dataset replicated across 3 regions.
- AWS Regions:
us-east-1(North Virginia),us-west-2(Oregon), andeu-central-1(Frankfurt). - Replication Factor: RF=3 (1 full replica per geographic region).
Compute Node Sizing Model:
* CockroachDB: 9x i4i.4xlarge nodes (3 nodes per region). Unified query, consensus, and storage.
* YugabyteDB: 9x i4i.4xlarge nodes (3 yb-tservers per region) + 3x c6i.large (yb-masters, 1 per region).
* TiDB: 9x i4i.4xlarge nodes (TiKV storage) + 6x c6i.4xlarge nodes (stateless TiDB SQL gateways) + 3x c6i.xlarge (PD nodes).Monthly Infrastructure Bill of Materials (BOM)
Pricing reflects standard on-demand AWS rates across US and EU availability zones:
| Cost Component | CockroachDB (Monthly) | YugabyteDB (Monthly) | TiDB (Monthly) | Architecture & Sizing Notes |
|---|---|---|---|---|
| Storage & Compute Nodes (Core) | $9,590.40 | $9,590.40 | $9,590.40 | 9x i4i.4xlarge ($1.48/hr avg across US/EU, 16 vCPU, 128GB RAM, 3.75TB NVMe). |
| Coordination / Master Nodes | $0.00 | $151.20 | $367.20 | CockroachDB: None. YugabyteDB: 3x c6i.large. TiDB: 3x c6i.xlarge (PD TSO). |
| Stateless Compute Layer | $0.00 | $0.00 | $2,937.60 | TiDB: 6x c6i.4xlarge ($0.68/hr avg) modeled for decoupled SQL parsing. |
| Inter-Region Data Egress | $3,110.40 | $3,110.40 | $3,888.00 | Sizing model: 20,000 writes/sec 1.5 KB 2 cross-region replications = ~155 TB egress @ $0.02/GB. |
| Intra-Region AZ Cross-Traffic | $777.60 | $777.60 | $1,296.00 | Client routing, internal Raft heartbeats, and TiDB Coprocessor gRPC exchanges. |
| Backup Storage (AWS S3) | $345.00 | $345.00 | $345.00 | 15 TB primary snapshot + daily delta retention in S3 Standard ($0.023/GB). |
| Application Load Balancers | $324.00 | $324.00 | $432.00 | AWS Network Load Balancers (NLB) spanning 3 regions for client traffic distribution. |
| Total Estimated Infrastructure | ~$14,147 | ~$14,298 | ~$18,856 | Modeled infrastructure baseline (excludes commercial enterprise licensing). |
Operational Overhead and Total Cost of Ownership (TCO)
1. Infrastructure Sizing Efficiency: CockroachDB and YugabyteDB operate at comparable baseline cloud infrastructure costs (~$14,200/month). CockroachDB's single-binary deployment eliminates the operational cost of dedicated master instances. YugabyteDB requires minimal compute overhead for its lightweight yb-master instances ($151/month).
2. Decoupled Architecture Sizing Considerations: In this theoretical architectural model, TiDB's decoupled architecture shows an estimated ~30% higher baseline cloud hosting cost (~$18,850/month modeled vs ~$14,200/month for unified architectures) when statically dimensioned for peak 100,000 QPS transactional throughput. Because the SQL layer is separated from TiKV storage, independent TiDB compute gateways and Placement Driver instances must be provisioned alongside storage daemons. Furthermore, inter-process communication between stateless TiDB nodes and TiKV storage daemons generates higher network transfer and inter-AZ data traffic costs. However, in production deployments characterized by bursty or diurnal query patterns, TiDB's decoupled architecture enables teams to independently autoscale stateless compute nodes during peak hours and downscale during lulls without modifying storage allocations, which can reduce real-world expenditure.
3. Software Distribution and Governance Models:
CockroachDB*: CockroachDB distributes its software under the CockroachDB Software License (CSL / Enterprise terms). Self-hosted enterprise deployments utilizing advanced operational capabilities—such as automated multi-region topology optimization, enterprise backup validation, and advanced RBAC—are subject to Cockroach Labs commercial licensing terms based on organization scale.
YugabyteDB*: YugabyteDB distributes its core DocDB and YSQL distributed database engines under the open-source Apache 2.0 license, including multi-region replication primitives and change data capture (CDC) integration within its core release, while offering managed cloud (YugabyteDB Aeon) and enterprise management capabilities under commercial licenses.
TiDB*: TiDB and its underlying storage engine TiKV (a Cloud Native Computing Foundation graduated project) are distributed under the open-source Apache 2.0 license. Self-hosted deployments are managed via open-source tools such as the TiDB Operator for Kubernetes, while fully managed operational tiers are provided through PingCAP's TiDB Cloud.
---
7. Distributed SQL Architectural Decision Matrix
The following decision matrix evaluates technical capabilities and architectural parameters across the three engines:
| Architectural Dimension | CockroachDB v24.2 | YugabyteDB v2.21 | TiDB v7.5 |
|---|---|---|---|
| Primary Implementation Language | Go (Query & Execution) | C (YSQL) / C++ (DocDB) | Go (SQL) / Rust (TiKV) / C++ (TiFlash) |
| Underlying Storage Engine | Pebble (Go LSM-Tree) | DocDB (Customized RocksDB) | Dual RocksDB (TiKV) & Columnar (TiFlash) |
| Process Model | Single binary (cockroach) | Dual daemons (yb-master, yb-tserver) | Tri-part disaggregated (tidb, pd, tikv) |
| Client Wire Protocol | PostgreSQL wire protocol | PostgreSQL wire & Cassandra (YCQL) | MySQL wire protocol |
| PostgreSQL Extension Parity | Partial (Limited custom functions) | High (PostGIS, pg_trgm, PL/pgSQL) | None (MySQL dialect) |
| Consensus Protocol | Multi-Raft with Range Leases | Multi-Raft with Leader Leases | Multi-Raft with Percolator 2PC |
| Distributed Commit Model | Parallel Commits (1 RTT write) | Two-Phase Commit with Status Tablets | Percolator 2PC with Central TSO |
| Default Isolation Level | Serializable (SSI) | Snapshot Isolation (SI) | Snapshot Isolation (SI) |
| Concurrency Model | Optimistic with Timestamp Pushes | Pessimistic Row Locking | Pessimistic (Default) or Optimistic |
| Cross-Continental Suitability | High (Geo-partitioning, table locality) | High (Tablespaces, follower reads) | Low to Moderate (TSO network penalty) |
| Real-Time HTAP Capability | Moderate (Vectorized OLAP on row store) | Moderate (Pushdown batch scans) | High (Dedicated TiFlash columnar engine) |
| Software Licensing Model | Source-Available (CSL / Commercial Enterprise Tiering) | Open Source (Apache 2.0 Core) | Open Source (Apache 2.0 Core / CNCF TiKV) |
---
8. Frequently Asked Questions
How do CockroachDB, YugabyteDB, and TiDB handle cross-region read latency without sacrificing consistency?
CockroachDB and YugabyteDB eliminate cross-region read latency by pinning Range Leaseholders (CockroachDB) or Tablet Leaders (YugabyteDB) to the geographic region where corresponding user data resides. Local reads are served directly from the local leaseholder without contacting replicas in other regions, guaranteeing linearizable consistency in under 3ms.
For global reference tables (such as country lists or tax rate schedules), CockroachDB supports Global Tables (which write to all regions via a multi-region Raft commit but allow instantaneous local reads everywhere), while YugabyteDB supports Follower Reads (yb_read_from_followers) that execute against local tablet followers under bounded staleness (typically sub-second).
TiDB relies on its centralized Placement Driver (PD) for timestamp allocation. Serving linearizable reads in a remote region requires fetching a read timestamp from the active PD leader, adding a cross-region network round-trip unless using stale read directives (AS OF SYSTEM TIME).
Why does CockroachDB default to Serializable isolation while YugabyteDB and TiDB default to Snapshot Isolation?
CockroachDB prioritizes absolute data correctness and mathematical safety above raw throughput under contention, adopting the stance that distributed systems must eliminate write skew anomalies at the database layer rather than leaving invariant enforcement to application developers. CockroachDB implements Serializable Snapshot Isolation (SSI) to catch read-write anti-dependencies and abort conflicting transactions.
YugabyteDB and TiDB default to Snapshot Isolation (SI) because the vast majority of enterprise transactional workloads (including banking transfers with explicit row locks) do not suffer from write skew if schemas utilize pessimistic locking (SELECT ... FOR UPDATE). Defaulting to Snapshot Isolation prevents cascading transaction retry storms and abort errors, providing predictable latency profiles under high write concurrency. Both YugabyteDB and TiDB allow teams to set SERIALIZABLE explicitly when strict mathematical serializability is required.
How does TiDB's disaggregated TiKV/TiFlash architecture isolate analytical queries from transactional workloads?
In traditional single-binary or coupled architectures (CockroachDB and YugabyteDB), running a heavy analytical aggregation query (such as scanning 50 million rows to calculate regional quarterly revenue) consumes CPU, block cache memory, and I/O bandwidth on the same nodes processing real-time transactional writes.
TiDB prevents this resource contention through TiFlash. TiFlash nodes join TiKV Raft groups as non-voting Raft Learners. Transactional mutations committed in TiKV stream asynchronously to TiFlash without participating in the Raft consensus write quorum. When an analyst runs an analytical aggregation, the TiDB cost-based optimizer detects the query complexity and routes execution entirely to TiFlash's columnar vectorized execution engine. The transactional TiKV cluster experiences zero I/O or memory degradation.
What causes transaction retry storms in distributed SQL, and how do you mitigate them at the client layer?
Transaction retry storms occur when multiple concurrent transactions attempt to read and write to the same row or key range under strict Serializable isolation. Under Serializable Snapshot Isolation (SSI), the database aborts conflicting transactions with SQLSTATE 40001 (serialization_failure).
If client applications respond by immediately retrying failed transactions without backoff, the influx of retried requests collides with newly arriving transactions. The cluster coordinators spend 100% of their CPU resources parsing, planning, and aborting conflicting transactions, causing system throughput to drop toward zero.
Mitigation requires two coordinated tactics:
1. Client-Side Decorrelated Jitter: Implement exponential backoff randomized with jitter (sleep = min(maxDelay, random(baseDelay, sleep * 3))) to desynchronize retrying threads.
2. Schema and Workload Optimization: Convert optimistic blind updates into pessimistic locking (SELECT ... FOR UPDATE), shard hot counter records across multiple rows, and batch high-frequency updates into localized aggregate tables.
What are the operational overheads and Day-2 maintenance differences between single-binary CockroachDB and multi-component TiDB?
CockroachDB offers a streamlined operational footprint among distributed SQL engines. Because every node is identical and packaged as a single static binary, rolling cluster upgrades, automated node decommissioning, and local backups are executed through simple command-line invocations without external dependencies.
TiDB requires managing three independent distributed systems: the stateless TiDB SQL compute layer, the etcd-backed Placement Driver (PD) quorum, and the stateful TiKV storage cluster (plus TiFlash if HTAP is enabled). Upgrades, dynamic scaling, and topology rebalancing require orchestrating distinct configuration files and process lifecycles. Production TiDB deployments typically require Kubernetes using the TiDB Operator to automate Day-2 lifecycle management, adding Kubernetes administrative complexity to the database operational burden.
---
Sources
- OLTP-Bench: An Extensible Testbed for Benchmarking Relational Databases
- CockroachDB Multi-Raft Engine Documentation
- CockroachDB Parallel Commits Architecture
- Cockroach Labs Cloud Report & Performance Benchmarks
- YugabyteDB DocDB Architectural Deep-Dive
- YugabyteDB Transaction Model and Isolation Levels
- YugabyteDB Distributed TPC-C Benchmark Analysis & Whitepaper
- TiDB Architecture and Internal Storage Specification
- TiFlash Columnar Engine Design (PingCAP)
- PingCAP TiDB Official TPC-C Benchmark Guide
- VLDB Paper: TiDB: A Raft-based HTAP Database (Huang et al., 2020)
- AWS EC2 On-Demand Instance Pricing & Sizing Framework