TPC-C (OLTP)
Headline: 3.85M TPS / 103.9M NOPM
Section titled “Headline: 3.85M TPS / 103.9M NOPM”Single machine. Durable WAL. All 5 TPC-C procedures correct.
PDB native wire protocol with compiled stored procedures. PG wire (PostgreSQL-compatible): 726K TPS at 32 workers (9.7x MariaDB).
Latest Result — Compiled Stored Procedures
Section titled “Latest Result — Compiled Stored Procedures”Machine: AWS c8g.metal-48xl (192 vCPU Graviton4, 384 GB DDR5, EBS-only) Protocol: PDB native wire with compiled stored procedures (CALL) Transaction mode: zero-copy-occ (overlay OCC, validation at commit) WAL: groupsync (durable, batched fsync on EBS) Procedures: All 5 TPC-C — NEWORD 45%, PAYMENT 43%, OSTAT 4%, DELIVERY 4%, SLEV 4% Client cache: None — all data access is server-side via stored procedures NOPM: Measured from actual NewOrder completion count (not derived from TPS) Duration: 60 seconds per worker count, warehouses = workers
| Workers | TPS | NOPM (measured) | TPM |
|---|---|---|---|
| 1 | 129,469 | 3,495,807 | 7,768,139 |
| 8 | 740,843 | 20,002,905 | 44,450,566 |
| 32 | 2,673,967 | 72,177,931 | 160,438,005 |
| 64 | 3,028,866 | 81,767,004 | 181,731,972 |
| 128 | 3,849,631 | 103,931,316 | 230,977,888 |
| 192 | 3,757,191 | 101,432,606 | 225,431,431 |
Zero errors across all worker counts.
Transaction Mode Comparison
Section titled “Transaction Mode Comparison”ParticleDB supports multiple transaction isolation modes. All results on the same hardware (c8g.metal-48xl), same workload, PDB wire CALL, groupsync WAL:
Zero-Copy OCC (Recommended)
Section titled “Zero-Copy OCC (Recommended)”Overlay-based OCC: all writes buffer per-transaction, OCC validation at COMMIT. No table-level locks. Zero dirty reads by construction.
| Workers | TPS | NOPM |
|---|---|---|
| 1 | 129,469 | 3.5M |
| 32 | 2,673,967 | 72.2M |
| 128 | 3,849,631 | 103.9M |
| 192 | 3,757,191 | 101.4M |
OCC (Classic)
Section titled “OCC (Classic)”Standard optimistic concurrency control with snapshot reads and write-set validation.
| Workers | TPS | NOPM |
|---|---|---|
| 128 | ~3,660,000 | ~98.8M |
| 192 | ~3,880,000 | ~104.8M |
Table-2PL + Per-Transaction Fsync (Strictest Durability)
Section titled “Table-2PL + Per-Transaction Fsync (Strictest Durability)”Exclusive table locks + per-transaction fsync() on EBS. This is the strictest
configuration: full serializability + full durability. Every committed transaction
is guaranteed on disk before acknowledgment.
--txn-mode table-2pl --wal-sync-mode sync
| Workers | TPS | NOPM | Errors |
|---|---|---|---|
| 1 | 125,920 | 3.4M | 0 |
| 8 | 793,080 | 21.4M | 0 |
| 32 | 2,647,145 | 71.5M | 0 |
Note: These numbers include per-transaction fsync on EBS (~1ms per fsync). The high throughput is because the WAL flusher batches concurrent fsyncs even in sync mode — 32 concurrent workers amortize the fsync cost across transactions.
How It Works
Section titled “How It Works”ParticleDB’s compiled stored procedure engine compiles PL/pgSQL procedure bodies into a typed IR at first CALL. Subsequent executions bypass SQL parsing entirely.
Client → CALL neword(1, 3, 42, 10)Server → [cached compiled IR] → 20 direct point operations → result Zero SQL parsing. Zero planning. Zero executor overhead.All 5 TPC-C procedures are semantically correct:
- NEWORD: SELECT INTO district, UPDATE district, INSERT oorder/new_order, FOR loop with stock SELECT/UPDATE + order_line INSERT
- PAYMENT: UPDATE warehouse/district, SELECT customer, UPDATE customer
- OSTAT: SELECT customer,
MAX(o_id)to find customer’s actual latest order, iterate order lines - DELIVERY: FOR each district:
MIN(no_o_id)for oldest undelivered, DELETE new_order, SELECTo_c_idfrom oorder, UPDATE oorder carrier,SUM(ol_amount)for balance, UPDATE order_line delivery dates, UPDATE customer balance - SLEV: 3-table JOIN with
COUNT(DISTINCT)— exact HammerDB SQL
Competition
Section titled “Competition”| Database | NOPM | Hardware | Nodes | Source |
|---|---|---|---|---|
| ParticleDB | 103,931,316 | c8g.metal 192vCPU | 1 | This benchmark |
| MariaDB 11.8 | 2,015,540 | EPYC 9655P 96c | 1 | MariaDB blog |
| PostgreSQL 17 | ~237,000 | EPYC 48c | 1 | pgbench TPC-C |
| YugabyteDB | 1,000,000 | 75x c5d.12xl | 75 | YB blog |
| CockroachDB | ~1,680,000 | Multi-node | N | CRDB docs |
Server Specifications
Section titled “Server Specifications”| Component | Spec |
|---|---|
| Instance | AWS c8g.metal-48xl |
| CPU | 192 vCPU (Graviton4 ARM64) |
| Memory | 384 GB DDR5 |
| Storage | EBS gp3 (network-attached, not local NVMe) |
| OS | Amazon Linux 2023 (aarch64) |
| WAL sync | groupsync (batched fsync, ~100us amortized) |
PG Wire Results (PostgreSQL-compatible protocol)
Section titled “PG Wire Results (PostgreSQL-compatible protocol)”Same compiled stored procedures, over PG wire (Unix socket, simple query protocol):
| Workers | TPS | NOPM (measured) |
|---|---|---|
| 1 | 96,000 | 2.6M |
| 8 | 305,000 | 8.2M |
| 32 | 726,000 | 19.6M |
| 64 | 269,000 | 7.3M |
PG wire peaks at 32 workers (9.7x MariaDB). Throughput drops at 64+ due to Unix socket and async I/O overhead.
Direct comparison: PostgreSQL 17.8 (same hardware, same HammerDB driver)
Section titled “Direct comparison: PostgreSQL 17.8 (same hardware, same HammerDB driver)”To honest-to-goodness compare, we ran HammerDB v5.0 TPROC-C against PostgreSQL 17.8 on the same Graviton4 hardware, with identical durability settings:
default_transaction_isolation = serializable | read_committedcommit_delay = 10commit_siblings = 5synchronous_commit = on100 warehouses, stored procedures, 1 min ramp + 5 min runPostgreSQL 17.8 results:
| Workers | NOPM (SERIALIZABLE) | NOPM (READ COMMITTED) |
|---|---|---|
| 1 | 20,332 | – |
| 8 | 99,460 | 97,146 |
| 16 | error | 146,178 |
| 32–192 | error | error |
At 16+ workers under either isolation level, PostgreSQL hit serialization conflicts and procedure errors (deadlocks / RAISEERROR) on a 100-warehouse dataset — we ran each cell to completion and HammerDB stopped reporting NOPM because the bench framework treats the errors as run failures. This is real PostgreSQL behavior under contention, not an infrastructure issue.
ParticleDB on the same hardware hits 3.85M NOPM at 128 workers with overlay zero-copy-OCC — a 26× advantage at peak, and 10× even at the workers-per-warehouse ratio where Postgres is healthy.
Correctness
Section titled “Correctness”Benchmark results verified with correctness test suites:
| Test | Result | Mode | Source | What it checks |
|---|---|---|---|---|
| Elle serializable | 50/50 PASS | OCC | jepsen-io/elle | Serialization-cycle detection via rw-dependency graphs |
| Hermitage isolation | 14/14 OK | OCC | ept/hermitage | All SQL isolation anomaly classes (G0, G1a/b/c, G2, etc.) |
| Bank invariant | 40/40 PASS | OCC | Our harness | Total balance preserved across concurrent transfers |
| Lost update | 40/40 PASS | OCC | Our harness | Read-modify-write atomicity under contention |
| Atomicity | 40/40 PASS | OCC | Our harness | All-or-nothing transaction commit |
| WAL crash recovery | 5/5 PASS | OCC | Our harness | SIGKILL + restart → data preserved |
Elle is the real serialization checker from the Jepsen project. It analyzes transaction dependency graphs to detect G0, G1a/b/c, G-Single, G2 (write skew), and all Adya anomaly classes. Our test runs multi-operation transactions (BEGIN; SELECT k1; UPDATE k2; COMMIT) with 8 concurrent clients — 200 transactions per iteration, 50 iterations (10,000 total transactions checked).
Note: The bank/lost-update/atomicity tests are our own psql-based harness (not Jepsen). Single-node only — no network partition or node failure injection. Distributed fault injection testing is planned after multi-node replication.
Reproduce It Yourself
Section titled “Reproduce It Yourself”1. Install ParticleDB
Section titled “1. Install ParticleDB”curl -fsSL get.particledb.ai | bash2. Start the server
Section titled “2. Start the server”# OCC mode with durable WAL (recommended)particledb start --no-auth --txn-mode zero-copy-occ --data-dir /tmp/pdb-tpcc3. Connect and run queries
Section titled “3. Connect and run queries”ParticleDB is PostgreSQL-compatible. Connect with any PG client:
psql -h 127.0.0.1 -p 5432
# Create a tableCREATE TABLE users (id INT PRIMARY KEY, name VARCHAR(100), email VARCHAR(200));
# Insert dataINSERT INTO users VALUES (1, 'Alice', 'alice@example.com');
# QuerySELECT * FROM users WHERE id = 1;4. Verify TPC-C performance
Section titled “4. Verify TPC-C performance”The TPC-C benchmark tool will be available as a separate download.
For now, you can verify basic transactional performance with pgbench:
pgbench -h 127.0.0.1 -p 5432 -i -s 10 # Initializepgbench -h 127.0.0.1 -p 5432 -c 8 -j 8 -T 30 # Run 8 clients, 30 secondsOur full TPC-C benchmark (all 5 stored procedures with the standard 45/43/4/4/4 mix) uses a custom Rust driver that will be released as open-source tooling.
Caveats (read these)
Section titled “Caveats (read these)”- Protocol difference: The 3.85M TPS headline uses PDB’s native wire protocol (binary framing, compiled stored procedures). The PG wire result (726K TPS at 32w) is the PostgreSQL-compatible comparison point. MariaDB’s 2.02M NOPM uses HammerDB with compiled stored procedures over the MySQL wire protocol.
- Custom benchmark: Results from ParticleDB’s Rust TPC-C driver, not HammerDB or BenchmarkSQL. The workload is TPC-C standard (5 procs, 45/43/4/4/4 mix) but the driver is ours.
- In-memory: All data fits in RAM. This is not a disk-resident benchmark. Bigger-than-RAM support is in development (see STORAGE_DESIGN.md).
- Low contention: TPC-C with warehouses = workers has minimal cross-warehouse contention. High-contention benchmarks (multiple writers to same rows) are planned.
- OSTAT limitation: Iterates a fixed loop (1..10 order lines) instead of CURSOR — 4% of mix
- Single node: No distributed consensus overhead. Multi-node benchmarks are planned.
- Correctness tests are single-node: No network partition or fault injection testing yet.
- WAL durability:
groupsyncbatches fsyncs but does NOT ack until fsync completes — this is durable. Same approach as PostgreSQL’scommit_delay.