Performance Benchmarks

InventDB v0.18 & PostgreSQL 18.2  |  March 2026

PostgreSQL is the gold standard of relational databases — battle-tested over 40 years, trusted by millions of deployments worldwide, and renowned for its reliability and query performance. We use PostgreSQL as our benchmark because that is the standard we hold ourselves to. Our goal is to learn from the best and make InventDB better with every release.

Below are side-by-side query performance measurements for InventDB and PostgreSQL across 143 queries in 18 categories. All times are warm-run totals in milliseconds (lower is faster). Tests were conducted on the same hardware under identical conditions.

Test Environment

Platform
Windows Server 2025
CPU
4 vCPU
Memory
16 GB RAM
Storage
EBS General Purpose SSD (gp3, up to 3,000 IOPS)
InventDB Version
v0.18
PostgreSQL Version
18.2

Database Configuration

Parameter InventDB PostgreSQL
Storage Model Segmented B-Link tree (100K records/segment) Standard heap + B-tree indexes
Encryption AES-256-GCM at rest None
Page Cache Disabled (page_cache = 0) shared_buffers ~4 GB
Document Cache Disabled N/A
Aggregate Cache Disabled N/A
Data Types 4 types: Customer, CustomerContact, CustomerDevice, CustomerInteraction
InventDB was tested with all application-level caches disabled and AES-256 encryption active on every read. PostgreSQL uses its default shared_buffers page cache (~4 GB) with no encryption.

10 Million Records (Equal Scale)

Both databases loaded with 2,500,000 records per type (10M total). Identical data, identical queries.

Metric InventDB PostgreSQL
Total Records 10,000,000 10,000,000
Records per Type 2,500,000 2,500,000
Segments per Type 25 Single table
Insert Throughput 18,941 rec/s 15,197 rec/s

Category Totals

Single-Threaded (ST)

143 queries, cold + warm run each. Times = category warm totals (ms).

Category InventDB PostgreSQL
Basic SELECT (7) 44 1,702
Exact Match (7) 71 7
Range (11) 112 7
LIKE (8) 435 54
Compound WHERE (12) 681 14
ORDER BY (12) 168 8,324
GROUP BY (14) 760 7,334
GROUP BY + WHERE (4) 16 1,902
JOIN 2-table (12) 3,955 16,354
JOIN 3-table (11) 13,141 63,948
JOIN 4-table (5) 2,169 38,981
Secondary Table (9) 76 1,399
Pagination (6) 180 422
NULL Handling (2) 90 250
HAVING (4) 292 3,742
Edge Case (8) 8 725
Complex (5) 3,616 13,238
DISTINCT (6) 380 5,885
Total Warm 26,194 164,288
Total Cold 85,704 181,053
Wall Clock 113.0s 380.2s

Multi-Threaded (4 Threads)

143 queries × 4 threads. Times = per-thread avg warm totals (ms).

Category InventDB PostgreSQL
Basic SELECT (7) 32 5,430
Exact Match (7) 214 6
Range (11) 457 6
LIKE (8) 329 89
Compound WHERE (12) 1,093 11
ORDER BY (12) 337 23,339
GROUP BY (14) 1,623 26,108
GROUP BY + WHERE (4) 20 5,533
JOIN 2-table (12) 7,240 48,805
JOIN 3-table (11) 18,900 220,444
JOIN 4-table (5) 5,655 158,815
Secondary Table (9) 118 3,161
Pagination (6) 255 1,194
NULL Handling (2) 26 740
HAVING (4) 572 10,093
Edge Case (8) 143 2,401
Complex (5) 7,969 30,463
DISTINCT (6) 1,196 13,995
Per-Thread Warm 46,179 550,633
Per-Thread Cold 72,359 617,293
Wall Clock 119.6s 1,281.7s

Per-Query Statistics

Distribution of individual query execution times across all 143 queries. All times in milliseconds.

Single-Threaded (143 queries)

Metric Cold (ms) Warm (ms)
InventDB PG InventDB PG
Average 355 1,257 183 1,149
Median (p50) 75 5 12 4
p90 729 2,390 434 3,474
p95 2,132 7,515 1,562 7,503
p99 3,209 19,734 2,327 20,011
Max 5,702 23,764 2,575 22,837

Multi-Threaded (4 threads)

Metric Cold (ms) Warm (ms)
InventDB PG InventDB PG
Average 779 3,950 323 3,850
Median (p50) 151 11 29 5
p90 2,960 10,486 905 8,727
p95 4,409 14,486 2,307 17,722
p99 7,492 76,671 3,536 71,579
Max 11,076 93,705 4,592 95,819

Both databases: 143 queries × 4 threads, all concurrent (identical contention model). PG GROUP BY excludes query 7.14.

Reading percentiles: The median (p50) shows the typical query time. p90 means 90% of queries complete within this time. p99 represents the tail latency — the slowest 1% of queries. A lower p99 indicates more consistent performance across all query types.

Query Time Distribution (Single-Threaded Warm)

How many queries fall into each latency bucket, and which categories they belong to. Based on 136 comparable warm-run queries at equal 10M scale.

InventDB v0.18

Latency Bucket Queries % of Total Bucket Sum Categories
0 – 10 ms 63 44% 230 ms GROUP BY (10), Edge Case (8), Range (7), Basic SELECT (6), Secondary Table (6), Exact Match (5), GROUP BY+WHERE (4), DISTINCT (4), LIKE (3), JOIN 2-table (3), HAVING (2), Compound WHERE (2), Pagination (2), NULL Handling (1)
11 – 50 ms 36 25% 665 ms ORDER BY (12), Compound WHERE (5), Range (4), Pagination (3), Secondary Table (3), Exact Match (2), Basic SELECT (1), LIKE (1), GROUP BY (1), JOIN 2-table (1), JOIN 3-table (1), HAVING (1), DISTINCT (1)
51 – 100 ms 7 5% 602 ms LIKE (3), Compound WHERE (2), Pagination (1), NULL Handling (1)
101 – 500 ms 27 19% 7,162 ms JOIN 2-table (6), JOIN 4-table (5), JOIN 3-table (4), Compound WHERE (3), GROUP BY (3), Complex (3), LIKE (1), HAVING (1), DISTINCT (1)
501 – 1,000 ms 1 1% 678 ms Complex (1)
1,000+ ms 9 6% 16,857 ms JOIN 3-table (6), JOIN 2-table (2), Complex (1)
69% of queries complete in under 50ms. The 9 queries above 1 second (6%) account for 64% of total warm time and are exclusively multi-table JOIN and Complex queries, which involve cross-type hash joins.

PostgreSQL 18.2

Latency Bucket Queries % of Total Bucket Sum Categories
0 – 10 ms 78 55% 88 ms Compound WHERE (12), Range (11), ORDER BY (10), LIKE (7), Exact Match (7), Edge Case (6), JOIN 2-table (5), Secondary Table (6), Pagination (5), Basic SELECT (3), JOIN 3-table (3), Complex (1), JOIN 4-table (1), NULL Handling (1)
11 – 50 ms 1 1% 32 ms LIKE (1)
51 – 100 ms 2 1% 135 ms JOIN 3-table (1), JOIN 2-table (1)
101 – 500 ms 24 17% 9,182 ms GROUP BY (10), DISTINCT (4), Basic SELECT (4), Secondary Table (2), HAVING (1), Pagination (1), NULL Handling (1), Edge Case (1)
501 – 1,000 ms 16 11% 9,091 ms GROUP BY (4), HAVING (3), DISTINCT (2), ORDER BY (2), JOIN 2-table (2), Secondary Table (1), Complex (1), Edge Case (1)
1,000+ ms 22 15% 145,760 ms JOIN 3-table (7), JOIN 2-table (4), JOIN 4-table (4), GROUP BY+WHERE (4), Complex (3)
55% of queries complete in under 10ms thanks to PostgreSQL's shared_buffers page cache providing instant indexed lookups. However, 22 queries (15%) exceed 1 second, accounting for 89% of total warm time — these are primarily multi-table JOINs, COUNT(DISTINCT), and full-table aggregations where PostgreSQL must scan large tables.

Key Observations (10M)

Query Time Distribution (Multi-Threaded, 4 Threads, Warm)

How many queries fall into each latency bucket under 4-thread contention. Both databases at equal 10M scale (2.5M/type). Times are per-thread average warm values across 143 queries.

InventDB v0.18

Latency Bucket Queries % of Total Bucket Sum Categories
0 – 10 ms 37 26% 108 ms GROUP BY (9), Basic SELECT (6), Edge Case (6), GROUP BY+WHERE (4), JOIN 2-table (3), Secondary Table (3), Pagination (2), HAVING (2), Compound WHERE (1), NULL Handling (1)
11 – 50 ms 57 40% 1,635 ms ORDER BY (12), Exact Match (7), Range (7), Compound WHERE (6), Secondary Table (6), LIKE (5), Distinct (4), GROUP BY (2), Pagination (2), Basic SELECT (1), JOIN 2-table (1), JOIN 3-table (1), NULL Handling (1), HAVING (1), Edge Case (1)
51 – 100 ms 11 8% 713 ms Range (4), LIKE (3), Compound WHERE (2), Pagination (1), Edge Case (1)
101 – 500 ms 13 9% 3,679 ms JOIN 2-table (5), Compound WHERE (3), GROUP BY (1), JOIN 3-table (1), Pagination (1), Complex (1), Distinct (1)
501 – 1,000 ms 11 8% 7,479 ms JOIN 3-table (3), GROUP BY (2), JOIN 4-table (2), JOIN 2-table (1), HAVING (1), Complex (1), Distinct (1)
1,000+ ms 14 10% 32,565 ms JOIN 3-table (6), JOIN 4-table (3), Complex (3), JOIN 2-table (2)
66% of queries complete in under 50ms even under 4-thread contention. Only 14 queries (10%) exceed 1 second, totaling just 33s — all multi-table JOINs and Complex queries.

PostgreSQL 18.2

Latency Bucket Queries % of Total Bucket Sum Categories
0 – 10 ms 75 52% 77 ms Compound WHERE (12), Range (11), ORDER BY (10), Exact Match (7), LIKE (7), Secondary Table (6), Edge Case (6), Pagination (5), JOIN 2-table (4), Basic SELECT (2), JOIN 3-table (2), JOIN 4-table (1), NULL Handling (1), Complex (1)
11 – 50 ms 3 2% 62 ms LIKE (1), JOIN 3-table (1), Complex (1)
51 – 100 ms 2 1% 118 ms JOIN 2-table (1), Edge Case (1)
101 – 500 ms 3 2% 722 ms ORDER BY (1), JOIN 4-table (1), Secondary Table (1)
501 – 1,000 ms 3 2% 2,312 ms Edge Case (1), Pagination (1), NULL Handling (1)
1,000+ ms 57 40% 547,342 ms GROUP BY (14), JOIN 3-table (8), JOIN 2-table (7), DISTINCT (6), Basic SELECT (5), GROUP BY+WHERE (4), HAVING (4), JOIN 4-table (3), Complex (3), ORDER BY (1), Secondary Table (2)
52% of queries under 10ms via PostgreSQL’s page cache for indexed lookups. But 57 queries (40%) exceed 1 second under contention, totaling 547s (vs InventDB’s 33s) — a 17× gap. All GROUP BY, DISTINCT, and most aggregation queries degrade heavily under MT contention.

Key Observations (10M MT)

Data Ingestion Performance

Detailed breakdown of the time to load 10,000,000 records (2.5M per type × 4 types) into each database.

InventDB

Phase Time
Batch Insert (all 10M records) 527.95s
Total 527.95s
Effective Throughput 18,941 rec/s

All indexes built inline during insert. Data encrypted (AES-256) on write. No post-insert index build or analysis needed.

PostgreSQL

Phase Time
COPY (bulk load, unlogged tables) 47.7s
Index Creation (B-tree on all columns) 208.4s
Foreign Key Constraints 8.8s
SET LOGGED (enable WAL) 354.4s
ANALYZE (statistics update) 12.9s
Total 658.1s
Effective Throughput 15,197 rec/s

Raw COPY throughput: 209,471 rec/s. Total includes all post-load operations required for production readiness (indexes, constraints, WAL, statistics).

PostgreSQL's raw COPY command is extremely fast (209K rec/s) but a production-ready load includes index creation, foreign key validation, enabling WAL logging, and gathering statistics. InventDB builds all indexes inline during the insert phase, with encryption active throughout.

100 Million Records (Equal Scale)

Both databases loaded with 25,000,000 records per type (100M total). Identical data, identical queries. Multi-threaded benchmark: 4 threads, each running all 143 queries independently (worst-case contention).

Metric InventDB PostgreSQL
Total Records 100,000,000 100,000,000
Records per Type 25,000,000 25,000,000
Segments per Type 250 Single table
Both databases tested at identical scale (25M records per type = 100M total). InventDB runs with all caches disabled and AES-256 encryption at rest. PostgreSQL uses its default ~4 GB shared_buffers page cache with no encryption. Each of 4 threads runs all 143 queries independently — maximum concurrent contention.

Category Totals

Single-Threaded (ST)

Both at 25M/type (100M). 143 queries, cold + warm run each. Times = category warm totals (ms).

Category InventDB PostgreSQL
Basic SELECT (7) 66 11,201
Exact Match (7) 87 20
Range (11) 115 18
LIKE (8) 600 30
Compound WHERE (12) 1,380 23
ORDER BY (12) 586 91,195
GROUP BY (14) 6,092 64,023
GROUP BY + WHERE (4) 173 16,510
JOIN 2-table (12) 53,721 400,509
JOIN 3-table (11) 182,172 1,483,001
JOIN 4-table (5) 23,037 932,276
Secondary Table (9) 150 12,290
Pagination (6) 484 3,946
NULL Handling (2) 187 2,108
HAVING (4) 2,258 104,487
Edge Case (8) 23 6,733
Complex (5) 106,015 341,894
DISTINCT (6) 6,023 58,414
Total Warm 383,169 3,528,678
Total Cold 1,684,233 4,194,721
Wall Clock 36.3 min 133.9 min

Multi-Threaded (4 Threads, Equal Scale)

Both at 25M/type (100M). 143 queries × 4 threads. Times = per-thread avg warm totals (ms).

Category InventDB PostgreSQL
Basic SELECT (7) 63 49,576
Exact Match (7) 203 25
Range (11) 299 19
LIKE (8) 268 49
Compound WHERE (12) 2,673 33
ORDER BY (12) 1,207 266,867
GROUP BY (14) 31,930 252,294
GROUP BY + WHERE (4) 222 61,599
JOIN 2-table (12) 168,986 1,476,743
JOIN 3-table (11) 350,780 4,740,037
JOIN 4-table (5) 60,836 4,539,029
Secondary Table (9) 360 489,524
Pagination (6) 995 93,817
NULL Handling (2) 125 110,332
HAVING (4) 13,244 639,116
Edge Case (8) 45 74,083
Complex (5) 215,091 1,131,351
DISTINCT (6) 9,022 397,762
Per-Thread Warm 856,349 14,322,256
Per-Thread Cold 2,744,252 15,539,728
Wall Clock 59.3 min 512.8 min

Per-Query Statistics

Distribution of individual query execution times across all 143 queries. Both databases at equal 100M scale (25M/type). All times in milliseconds.

Single-Threaded (143 queries)

Metric Cold (ms) Warm (ms)
InventDB PG InventDB PG
Average 11,405 29,130 2,680 24,676
Median (p50) 299 9 33 8
p90 24,831 77,540 4,303 78,253
p95 84,065 163,653 22,590 166,776
p99 255,451 335,093 36,079 335,929
Max 290,197 448,034 86,159 440,885

Both at 25M/type (100M). PG query 7.14 excluded.

Multi-Threaded (143 queries, equal 100M, warm)

Metric Warm (ms)
InventDB PG
Average 5,989 100,155
Median (p50) 44 17
p90 12,041 283,610
p95 32,747 527,609
p99 107,870 1,432,238
Max 172,887 1,938,575

Both at 25M/type (100M). Per-thread average across 4 threads, each running all 143 queries.

Reading percentiles: The median (p50) shows the typical query time. p90 means 90% of queries complete within this time. p99 represents the tail latency — the slowest 1% of queries. Under MT contention, PostgreSQL’s p99 (1.43M ms = 24 min per query) is 13.3× worse than InventDB’s p99 (108s = 1.8 min per query).

Query Time Distribution (Single-Threaded Warm)

How many queries fall into each latency bucket. Based on 143 warm-run queries at equal 100M scale (25M/type).

InventDB v0.18

Latency Bucket Queries % of Total Bucket Sum Categories
0 – 10 ms 53 37% 294 ms GROUP BY (9), Edge Case (7), Basic SELECT (6), Range (6), Exact Match (5), Secondary Table (5), LIKE (4), JOIN 2-table (3), Distinct (3), HAVING (2), Compound WHERE (1), Pagination (1), NULL Handling (1)
11 – 50 ms 26 18% 653 ms Range (5), Compound WHERE (5), ORDER BY (4), Secondary Table (4), Exact Match (2), GROUP BY+WHERE (2), Pagination (2), Edge Case (1), Distinct (1)
51 – 100 ms 19 13% 1,194 ms ORDER BY (8), Compound WHERE (3), GROUP BY+WHERE (2), Pagination (2), Basic SELECT (1), GROUP BY (1), JOIN 2-table (1), JOIN 3-table (1)
101 – 500 ms 11 8% 2,624 ms LIKE (4), Compound WHERE (2), GROUP BY (1), Pagination (1), NULL Handling (1), HAVING (1), Distinct (1)
501 – 1,000 ms 1 1% 644 ms Compound WHERE (1)
1,000+ ms 33 23% 377,760 ms JOIN 3-table (10), JOIN 2-table (8), JOIN 4-table (5), Complex (5), GROUP BY (3), HAVING (1), Distinct (1)
55% of queries complete in under 50ms. The 33 queries above 1 second (23%) account for 99% of total warm time and are dominated by multi-table JOINs and Complex queries, which scale quadratically with data volume.

PostgreSQL 18.2

Latency Bucket Queries % of Total Bucket Sum Categories
0 – 10 ms 74 52% 90 ms Compound WHERE (12), Range (11), ORDER BY (10), LIKE (8), Exact Match (7), Edge Case (6), Secondary Table (5), Pagination (5), JOIN 2-table (3), Basic SELECT (2), JOIN 3-table (2), Complex (1), NULL Handling (1), JOIN 4-table (1)
11 – 50 ms 0 0%
51 – 100 ms 0 0%
101 – 500 ms 4 3% 800 ms JOIN 2-table (2), JOIN 3-table (1), Complex (1)
501 – 1,000 ms 2 1% 1,208 ms Basic SELECT (1), Secondary Table (1)
1,000+ ms 63 44% 3,526,555 ms GROUP BY (14), JOIN 3-table (8), JOIN 2-table (7), DISTINCT (6), GROUP BY+WHERE (4), HAVING (4), Complex (3), JOIN 4-table (4), Basic SELECT (4), Secondary Table (3), Edge Case (2), Pagination (1), NULL Handling (1), ORDER BY (2)
PG at equal 100M scale: PostgreSQL's page cache still handles indexed lookups, but analytical queries (GROUP BY, DISTINCT, JOINs) are dramatically slower at 25M/type. The heavy queries dominate total execution time.

Key Observations (100M)

Query Time Distribution (Multi-Threaded, 4 Threads, Warm)

How many queries fall into each latency bucket under 4-thread contention. Both databases at equal 100M scale (25M/type). Times are per-thread average warm values across 143 queries.

InventDB v0.18

Latency Bucket Queries % of Total Bucket Sum Categories
0 – 10 ms 20 14% 66 ms Edge Case (6), Basic SELECT (5), JOIN 2-table (3), GROUP BY (2), Secondary Table (2), NULL Handling (1), Distinct (1)
11 – 50 ms 56 39% 1,496 ms Range (11), LIKE (8), Exact Match (7), GROUP BY (7), Compound WHERE (6), Secondary Table (5), Basic SELECT (2), GROUP BY+WHERE (2), Pagination (2), HAVING (2), Edge Case (2), Distinct (2)
51 – 100 ms 14 10% 1,108 ms ORDER BY (6), Compound WHERE (2), GROUP BY+WHERE (2), GROUP BY (1), Secondary Table (1), Pagination (1), Distinct (1)
101 – 500 ms 15 10% 2,191 ms ORDER BY (6), Compound WHERE (3), Pagination (2), JOIN 2-table (1), JOIN 3-table (1), Secondary Table (1), NULL Handling (1)
501 – 1,000 ms 2 1% 1,540 ms Pagination (1), Distinct (1)
1,000+ ms 36 25% 849,948 ms JOIN 3-table (10), JOIN 2-table (8), JOIN 4-table (5), Complex (5), GROUP BY (4), HAVING (2), Compound WHERE (1), Distinct (1)
53% of queries complete in under 50ms and 63% under 100ms at 100M scale under 4-thread contention. The 36 queries above 1 second (25%) are predominantly multi-table JOINs and Complex queries, totaling 850s — dominated by hash-join operations across 25M-record tables.

PostgreSQL 18.2

Latency Bucket Queries % of Total Bucket Sum Categories
0 – 10 ms 67 47% 95 ms Range (11), Compound WHERE (11), ORDER BY (9), Exact Match (7), LIKE (6), Edge Case (5), JOIN 2-table (4), Secondary Table (4), Pagination (4), Basic SELECT (2), JOIN 3-table (2), JOIN 4-table (1), Complex (1)
11 – 50 ms 8 6% 132 ms LIKE (2), Compound WHERE (1), ORDER BY (1), Pagination (1), NULL Handling (1), Edge Case (1), Secondary Table (1)
51 – 100 ms 0 0%
101 – 500 ms 2 1% 336 ms JOIN 2-table (1), Secondary Table (1)
501 – 1,000 ms 2 1% 1,424 ms JOIN 2-table (1), JOIN 3-table (1)
1,000+ ms 64 45% 14,320,309 ms GROUP BY (14), JOIN 3-table (8), JOIN 2-table (6), DISTINCT (6), Basic SELECT (5), GROUP BY+WHERE (4), JOIN 4-table (4), HAVING (4), Complex (4), Secondary Table (3), ORDER BY (2), Edge Case (2), Pagination (1), NULL Handling (1)
47% of queries under 10ms via PostgreSQL’s page cache. However, 64 queries (45%) exceed 1 second under 4-thread contention, totaling 14,320s (4.0 hours) vs InventDB’s 850s (14.2 min) — a 16.8× gap. Every GROUP BY, DISTINCT, HAVING, and all JOIN aggregation queries fall into the 1s+ bucket.

Key Observations (100M MT)


Methodology

Query Suite

143 queries across 18 categories covering: basic SELECT, exact match, range, LIKE, compound WHERE, ORDER BY, GROUP BY (with and without WHERE), 2/3/4-table JOINs, secondary table queries, pagination, NULL handling, HAVING, edge cases, complex multi-stage operations, and DISTINCT. PostgreSQL includes one additional query (7.14: GROUP BY first_name, last_name) excluded from comparisons.

Measurement

Data Generation

Both databases use the same schema and data generation logic. Customer records include FirstName, LastName, Age, Salary, DateOfBirth, Email, FullName, and nested Address fields (Street, City, State, PostalCode). Related types (Contact, Device, Interaction) are linked via CustomerId.

Differences to Note


Benchmark History

Performance progression across InventDB releases. PostgreSQL baseline (18.2) is unchanged across all versions. All tests run with InventDB caches disabled and AES-256 encryption active.

Version Date Config 10M ST Overall 10M MT Overall 100M ST Overall 100M MT Overall
v0.6 2026-03-05 All caches disabled 5.1× faster 12.1× faster 6.9× faster 17.1× faster
v0.9b 2026-03-11 All caches disabled 6.0× faster 12.5× faster 9.3× faster 16.5× faster
v0.9c 2026-03-13 All caches disabled 6.0× faster 11.7× faster 8.0× faster 16.4× faster
v0.12 2026-03-14 All caches disabled 6.4× faster 12.1× faster 8.1× faster 15.7× faster
v0.15 2026-03-15 All caches disabled 6.1× faster 12.0× faster 8.0× faster 17.0× faster
v0.18 2026-03-16 All caches disabled 6.3× faster 11.9× faster 9.2× faster 16.7× faster
As InventDB evolves, new benchmark snapshots will be added here. Each snapshot preserves the overall speedup ratios at that point in time, allowing readers to track progress across releases.