Benchmarks: encrypted, at 10 million rows.
Query and transaction benchmarks over 10 million rows, run in the shipping configuration with AES-256 encryption on, against PostgreSQL 18 and SQLite. Built-in capabilities are compared separately, against PostgreSQL, MongoDB and SQLite.
Two platforms, measured separately and published separately. How we test →
Measured on the dedicated ARM fleet: one Graviton machine per engine, identical spec, the same 10M-record dataset. InventDB runs with AES-256 encryption on. Cold = a query's first execution on an established connection; warm = a repeat of the same query.
Measured August 2026, v0.597
143-query shared set
The same 143 queries in each engine's dialect, over 10 million rows: 2.5M across each of four types. Figures are cold / warm milliseconds summed per category. InventDB runs with AES-256 encryption on; PostgreSQL 18 and SQLite run unencrypted at their tuned defaults, with an index on every column.
| Category | Queries | InventDB (in-process)cold / warm ms | InventDB (client/server)cold / warm ms | PostgreSQLcold / warm ms | SQLitecold / warm ms |
|---|---|---|---|---|---|
| Basic SELECT | 7 | 142 / 31 | 13 / 13 | 406 / 398 | 137 / 11 |
| Complex | 5 | 8,137 / 4,163 | 4,143 / 4,100 | 6,629 / 6,532 | 27,810 / 27,617 |
| Compound WHERE | 12 | 3,415 / 1,938 | 2,264 / 1,993 | 999 / 993 | 9 / 5 |
| Distinct | 6 | 1,131 / 991 | 120 / 119 | 2,351 / 2,341 | 221 / 216 |
| Edge Case | 8 | 308 / 85 | 90 / 90 | 504 / 402 | 661 / 657 |
| Exact Match | 7 | 581 / 91 | 115 / 103 | 4 / 3 | 1 / 0 |
| GROUP BY | 14 | 3,437 / 834 | 847 / 826 | 7,149 / 7,136 | 19,439 / 20,401 |
| GROUP BY+WHERE | 4 | 23,595 / 241 | 255 / 254 | 1,143 / 1,143 | 7,901 / 7,687 |
| HAVING | 4 | 344 / 313 | 315 / 310 | 2,875 / 2,912 | 7,878 / 7,841 |
| JOIN 2-table | 12 | 18,967 / 4,115 | 4,296 / 4,290 | 11,673 / 11,408 | 44,717 / 44,496 |
| JOIN 3-table | 11 | 41,282 / 6,423 | 6,405 / 6,550 | 60,062 / 59,440 | 141,941 / 140,766 |
| JOIN 4-table | 5 | 9,226 / 1,702 | 1,687 / 1,779 | 44,914 / 45,468 | 107,183 / 107,148 |
| LIKE | 8 | 1,570 / 257 | 356 / 277 | 7 / 6 | 1 / 1 |
| NULL Handling | 2 | 393 / 92 | 68 / 63 | 111 / 97 | 57 / 44 |
| ORDER BY | 12 | 3,177 / 717 | 917 / 751 | 48 / 45 | 157 / 139 |
| Pagination | 6 | 854 / 154 | 150 / 147 | 266 / 243 | 83 / 82 |
| Range | 11 | 448 / 16 | 54 / 36 | 12 / 5 | 5 / 1 |
| Secondary Table | 9 | 662 / 84 | 84 / 75 | 652 / 638 | 548 / 525 |
| Total, single client | 143 | 117,669 / 22,247 | 22,179 / 21,777 | 139,807 / 139,209 | 358,746 / 357,636 |
| Total, 4 parallel clients | 143 | — / 65,404 | — / 59,659 | — / 383,428 | — / 1,051,993 |
Four clients run the whole set at once against one shared database; those figures are the average per client, so each engine does four times the work in the time shown. InventDB answers 143 of 143; SQLite answers 139.
Measured August 2026, v0.597
3,551-query full battery
The complete battery across 28 categories, same data and same machine class. Figures are cold / warm milliseconds summed per category.
| Category | Queries | InventDB (in-process)cold / warm ms | InventDB (client/server)cold / warm ms | PostgreSQLcold / warm ms | SQLitecold / warm ms |
|---|---|---|---|---|---|
| Basic SELECT | 48 | 799 / 380 | 276 / 218 | 534 / 507 | 142 / 13 |
| Complex | 45 | 14,714 / 14,253 | 13,811 / 13,303 | 6,970 / 6,943 | 2,420 / 2,416 |
| Compound WHERE | 1,860 | 80,123 / 21,179 | 25,336 / 24,912 | 1,051 / 1,039 | 14,769 / 14,720 |
| COUNT DISTINCT | 40 | 95,696 / 25,493 | 24,804 / 24,723 | 55,964 / 55,845 | 12,836 / 12,888 |
| DISTINCT | 5 | 64 / 64 | 74 / 71 | 1,118 / 1,126 | 3 / 2 |
| Exact Match | 240 | 5,505 / 4,231 | 5,333 / 4,904 | 164 / 164 | 47 / 39 |
| GROUP BY | 20 | 4,931 / 1,423 | 1,450 / 1,447 | 7,765 / 7,766 | 34,291 / 34,318 |
| GROUP BY+WHERE | 184 | 141,609 / 37,161 | 39,112 / 39,029 | 27,524 / 27,519 | 112,133 / 112,296 |
| HAVING | 16 | 51 / 51 | 62 / 62 | 4,146 / 4,156 | 2,743 / 2,743 |
| IN / NOT IN | 14 | 837 / 755 | 837 / 775 | 1,511 / 1,509 | 2,116 / 2,117 |
| JOIN + GROUP BY | 2 | 1,332 / 690 | 727 / 713 | 4,218 / 4,190 | 11,413 / 11,388 |
| JOIN + ORDER BY | 4 | 1,965 / 349 | 1,722 / 459 | 8 / 5 | 2 / 1 |
| JOIN 2-table | 9 | 3,966 / 419 | 473 / 474 | 1,509 / 1,238 | 1,695 / 1,664 |
| JOIN 3-table | 6 | 914 / 349 | 381 / 373 | 11 / 7 | 2 / 2 |
| JOIN 4-table | 1 | 349 / 117 | 124 / 124 | 2 / 2 | 1 / 1 |
| JOIN 5-table | 2 | 232 / 173 | 219 / 181 | 8 / 7 | 1 / 1 |
| LIKE | 180 | 12,884 / 11,994 | 12,462 / 12,367 | 10,832 / 10,755 | 17,327 / 17,305 |
| Nested/Array | 30 | 137 / 40 | 242 / 225 | — | — |
| Nested/Object | 10 | 44 / 7 | 27 / 23 | — | — |
| NULL Handling | 16 | 137 / 135 | 149 / 150 | 784 / 784 | 333 / 332 |
| ORDER BY | 16 | 2,156 / 372 | 640 / 413 | 10 / 20 | 2 / 1 |
| ORDER BY multi | 64 | 29,039 / 25,545 | 30,160 / 26,204 | 4,016 / 4,018 | 11,806 / 11,803 |
| ORDER BY+WHERE | 320 | 12,135 / 9,239 | 11,107 / 10,173 | 178 / 169 | 58 / 49 |
| Pagination | 80 | 5,453 / 3,278 | 3,472 / 3,465 | 162 / 159 | 25 / 11 |
| Projection | 28 | 52 / 50 | 81 / 80 | 7 / 7 | 1 / 0 |
| Range | 253 | 5,163 / 823 | 1,508 / 1,409 | 1,182 / 1,179 | 1,121 / 1,108 |
| Scalar fn | 52 | 608 / 526 | 591 / 586 | 7,526 / 7,505 | 11,772 / 11,758 |
| Secondary Table | 6 | 6 / 5 | 10 / 10 | 333 / 296 | 63 / 10 |
| Total, single client | 3,551 | 420,899 / 159,103 | 175,190 / 166,872 | 137,534 / 136,915 | 237,123 / 236,986 |
| Total, 4 parallel clients | 3,551 | — / 432,441 | — / 413,178 | — / 347,439 | — / 574,517 |
InventDB answers 3,551 of 3,551; PostgreSQL and SQLite each answer 3,511. Three categories carry most of InventDB’s remaining time here: GROUP BY + WHERE at 23% of the warm total, with ORDER BY multi and COUNT DISTINCT at 16% each. All are published as measured.
Both execution modes
In-process and client/server
InventDB is the only engine here that runs both ways, so it is measured both ways. PostgreSQL has no in-process mode; SQLite has no server mode. Warm totals in seconds.
| Suite | InventDBin-process | InventDBclient/server | PostgreSQLclient/server | SQLitein-process |
|---|---|---|---|---|
| 3,551 battery, 1 client | 177.7 | 191.4 | 136.9 | 237.0 |
| 3,551 battery, 4 clients | 458.9 | 481.6 | 347.4 | 574.5 |
| 143-query set, 1 client | 35.8 | 37.2 | 139.2 | 357.6 |
| 143-query set, 4 clients | 92.1 | 87.6 | 383.4 | 1,052.0 |
The server layer costs little on the large battery and a great deal on the small one. Under four clients on the 3,551-query battery it is faster than running in-process (413.2 vs 432.4 s): one server process with a shared database beats four callers contending inside one process on two cores. On the 143-query set the same four clients cost -9% (59.7 vs 65.4 s): that set is small enough that per-request transport dominates, with far fewer queries to amortise it over.
Transactions
TPC-C
Four warehouses, 10,000 transactions per leg, the full TPC-C mix. Durability matched across engines: PostgreSQL synchronous_commit=on, SQLite WAL with synchronous=FULL, InventDB checkpointing throughout. Transactions per second; higher is better.
| Leg | InventDBin-process | InventDBclient/server | PostgreSQLclient/server | SQLitein-process |
|---|---|---|---|---|
| Sequential | 127.8 | 75.4 | 181.3 | 387.6 |
| 4 threads | 233.0 | 112.3 | 360.0 | 127.1 |
| Scaling, 4 threads vs sequential | 1.82× | 1.49× | 1.99× | 0.33× |
| Transactions completed | 10,000 / 10,000 | 10,000 / 10,000 | 10,000 / 10,000 | 10,000 / 10,000 |
Every engine completes all 10,000 transactions with zero errors, and every InventDB figure here comes from a run that passed all eleven exact-accounting identities: balances that must hold to the cent across warehouses, districts and customers, which the other engines do not check at all. SQLite's four-thread throughput falls below its own sequential figure: the single-writer model. A TPC-C transaction is eight or more statements, so a client/server engine pays a round trip on every one of them.
Cold = the first execution of a query on an established connection; warm = a repeat of the same query. The engine runs in its shipping configuration, and encryption at rest stays on the whole time.
Measured August 2026
143-query shared set
The same 143 queries in each engine's dialect, over 10 million rows: 2.5M across each of four types, on one machine. Figures are cold / warm milliseconds summed per category. InventDB runs in its shipping configuration with AES-256 encryption on; PostgreSQL 18 and SQLite run unencrypted at their defaults.
| Category | Queries | InventDB (in-process)cold / warm ms | InventDB (client/server)cold / warm ms | PostgreSQLcold / warm ms | SQLitecold / warm ms |
|---|---|---|---|---|---|
| Basic SELECT | 7 | 61 / 11 | 9 / 7 | 5,429 / 1,696 | 700 / 29 |
| Complex | 5 | 3,171 / 2,498 | 3,256 / 3,135 | 19,039 / 18,591 | 36,247 / 35,993 |
| Compound WHERE | 12 | 1,298 / 462 | 432 / 423 | 27,067 / 13,546 | 34 / 9 |
| DISTINCT | 6 | 477 / 290 | 46 / 47 | 15,796 / 3,528 | 1,136 / 248 |
| Edge Case | 8 | 20 / 19 | 27 / 27 | 421 / 681 | 806 / 806 |
| Exact Match | 7 | 179 / 16 | 34 / 33 | 106 / 23 | 2 / 1 |
| GROUP BY | 14 | 1,463 / 540 | 596 / 640 | 9,474 / 6,703 | 32,718 / 33,123 |
| GROUP BY + WHERE | 4 | 8,573 / 200 | 225 / 209 | 3,637 / 2,048 | 19,586 / 18,402 |
| HAVING | 4 | 196 / 199 | 287 / 271 | 6,086 / 5,477 | 8,538 / 8,780 |
| JOIN 2-table | 12 | 5,498 / 2,613 | 3,124 / 3,093 | 25,526 / 24,174 | 146,682 / 140,355 |
| JOIN 3-table | 11 | 19,757 / 9,487 | 10,402 / 10,480 | 93,154 / 79,615 | 264,061 / 232,881 |
| JOIN 4-table | 5 | 3,406 / 1,123 | 1,696 / 1,769 | 56,967 / 51,875 | 194,025 / 194,300 |
| LIKE | 8 | 1,015 / 105 | 114 / 90 | 71 / 53 | 2 / 2 |
| NULL Handling | 2 | 230 / 8 | 21 / 15 | 641 / 173 | 300 / 44 |
| ORDER BY | 12 | 1,019 / 122 | 201 / 200 | 10,834 / 10,349 | 372 / 294 |
| Pagination | 6 | 91 / 35 | 45 / 44 | 1,426 / 244 | 99 / 92 |
| Range | 11 | 252 / 21 | 54 / 56 | 28 / 18 | 22 / 3 |
| Secondary Table | 9 | 378 / 27 | 56 / 60 | 3,070 / 796 | 2,044 / 1,808 |
| All categories | 143 | 47,084 / 17,777 | 20,627 / 20,598 | 278,772 / 219,590 | 707,374 / 667,170 |
Each cell is cold / warm total milliseconds for that category. Cold = first execution on the connection; warm = a second execution of the same query on the same connection. SQLite completed 138 of 143 queries; the 5 it did not accept contribute nothing to its totals, so its column covers less work than the other two.
| Engine | Cold msper client | Warm msper client | Queries completed |
|---|---|---|---|
| InventDB client/server | 43,041 | 44,333 | 143/143 |
| PostgreSQL | 1,025,287 | 1,015,137 | 143/143 |
| SQLite | 1,144,177 | 1,132,102 | 138/143 |
Four clients run the whole battery at once against one shared database. Figures are the average per client, so each engine does four times the work of the single-client table in the time shown. Cold and warm converge here: four clients saturate a four-core machine, so a repeat has no spare capacity to exploit. For InventDB the two differ by 0.4%, which is within normal variation; read them as one number. No category breakdown is published for this leg.
| Clients | Warm msper client | Queries completed |
|---|---|---|
| Single client | 17,777 | 143/143 |
| 4 parallel clients | 32,550 | 143/143 |
The same 143 queries with the engine embedded, no HTTP layer: the route an application takes when it links InventDB rather than calling a server. Against the client/server figures above: 17,777 vs 20,598 ms for one client, 32,550 vs 44,333 ms for four. The difference is the transport. No cold column: an embedded engine has no server to warm beforehand, so its first pass includes opening the dataset, a cost the other legs exclude, which would make the columns mean different things.
Measured August 2026
3,551-query full battery
The complete SQL battery: 3,551 queries across 28 categories, the same dataset and machine. This is a different and much larger set than the 143-query one above; the two are never totalled together. InventDB is recorded twice, once in-process and once over its HTTP client/server path, because they are different execution routes.
| Category | Queries | InventDB (in-process)cold / warm ms | InventDB (client/server)cold / warm ms | PostgreSQL (client/server)cold / warm ms | SQLite (in-process)cold / warm ms |
|---|---|---|---|---|---|
| GROUP BY + WHERE | 184 | 39,416 / 19,825 | 21,139 / 20,877 | 67,131 / 66,949 | 105,461 / 105,718 |
| COUNT DISTINCT | 40 | 41,825 / 21,993 | 20,986 / 20,462 | 346,357 / 335,021 | 14,157 / 13,793 |
| Compound WHERE | 1,860 | 16,398 / 5,036 | 13,370 / 13,256 | 5,956 / 5,924 | 16,915 / 16,136 |
| ORDER BY + WHERE | 320 | 5,317 / 3,279 | 5,193 / 5,200 | 335 / 222 | 123 / 97 |
| Range | 253 | 1,415 / 488 | 2,051 / 2,016 | 4,293 / 3,025 | 2,728 / 1,220 |
| GROUP BY | 20 | 2,250 / 1,039 | 1,223 / 1,210 | 14,095 / 14,000 | 33,536 / 32,720 |
| Complex | 45 | 2,446 / 1,701 | 1,718 / 1,702 | 15,624 / 9,884 | 2,961 / 2,915 |
| ORDER BY multi | 64 | 8,414 / 5,335 | 5,785 / 5,717 | 16,261 / 15,482 | 13,865 / 14,520 |
| Scalar fn | 52 | 296 / 278 | 312 / 310 | 13,417 / 13,059 | 15,674 / 15,681 |
| JOIN 2-table | 9 | 3,326 / 863 | 883 / 847 | 4,776 / 2,446 | 4,031 / 2,010 |
| Pagination | 80 | 2,152 / 616 | 800 / 798 | 769 / 201 | 27 / 18 |
| LIKE | 180 | 2,144 / 1,633 | 2,878 / 2,826 | 32,496 / 26,510 | 26,028 / 19,476 |
| Exact Match | 240 | 2,485 / 747 | 2,454 / 2,383 | 1,398 / 1,039 | 494 / 61 |
| JOIN 3-table | 6 | 735 / 26 | 135 / 130 | 160 / 13 | 207 / 4 |
| JOIN + GROUP BY | 2 | 1,027 / 650 | 674 / 656 | 6,683 / 6,667 | 21,021 / 13,435 |
| Basic SELECT | 48 | 685 / 301 | 161 / 154 | 5,163 / 875 | 2,149 / 29 |
| JOIN + ORDER BY | 4 | 1,166 / 123 | 119 / 118 | 387 / 9 | 4 / 2 |
| JOIN 5-table | 2 | 15 / 14 | 72 / 64 | 25 / 15 | 4 / 1 |
| JOIN 4-table | 1 | 321 / 9 | 48 / 47 | 79 / 3 | 110 / 1 |
| IN / NOT IN | 14 | 144 / 141 | 153 / 148 | 2,199 / 2,251 | 2,507 / 2,822 |
| ORDER BY | 16 | 1,381 / 62 | 102 / 101 | 52 / 13 | 12 / 2 |
| Projection | 28 | 11 / 11 | 33 / 33 | 13 / 12 | 4 / 3 |
| HAVING | 16 | 16 / 15 | 28 / 28 | 4,327 / 4,391 | 3,180 / 3,146 |
| NULL Handling | 16 | 16 / 13 | 24 / 27 | 1,378 / 1,316 | 475 / 360 |
| DISTINCT | 5 | 11 / 11 | 18 / 18 | 4,117 / 1,540 | 11 / 3 |
| Secondary Table | 6 | 4 / 1 | 6 / 6 | 599 / 545 | 214 / 18 |
| Nested/Object | 10 | 52 / 23 | 31 / 29 | — | — |
| Nested/Array | 30 | 270 / 207 | 321 / 313 | — | — |
| All categories | 3,551 | 133,740 / 64,439 | 80,717 / 79,475 | 548,090 / 511,412 | 265,898 / 244,191 |
| Category | Queries | InventDB (in-process)cold / warm ms | InventDB (client/server)cold / warm ms | PostgreSQL (client/server)cold / warm ms | SQLite (in-process)cold / warm ms |
|---|---|---|---|---|---|
| GROUP BY + WHERE | 184 | 59,579 / 43,064 | 49,857 / 51,345 | 209,552 / 216,931 | 190,558 / 189,998 |
| COUNT DISTINCT | 40 | 53,260 / 35,714 | 34,202 / 34,612 | 641,472 / 646,087 | 20,579 / 20,944 |
| Range | 253 | 2,787 / 838 | 4,582 / 4,964 | 9,507 / 9,007 | 2,338 / 2,381 |
| ORDER BY + WHERE | 320 | 4,666 / 4,593 | 11,211 / 9,258 | 438 / 289 | 143 / 154 |
| Compound WHERE | 1,860 | 26,075 / 7,950 | 23,624 / 23,278 | 22,299 / 22,141 | 22,994 / 21,804 |
| ORDER BY multi | 64 | 15,636 / 12,433 | 13,222 / 13,391 | 35,574 / 34,374 | 26,411 / 26,986 |
| Complex | 45 | 5,065 / 5,509 | 5,447 / 5,743 | 30,317 / 32,593 | 5,723 / 5,292 |
| GROUP BY | 20 | 3,548 / 2,046 | 2,638 / 2,660 | 50,938 / 51,844 | 52,786 / 51,220 |
| LIKE | 180 | 3,531 / 2,839 | 5,743 / 5,680 | 100,262 / 92,587 | 35,543 / 35,070 |
| Scalar fn | 52 | 536 / 516 | 1,275 / 1,347 | 38,718 / 37,775 | 94,775 / 93,329 |
| JOIN 2-table | 9 | 2,222 / 1,074 | 1,589 / 1,371 | 8,600 / 7,867 | 12,173 / 9,739 |
| Pagination | 80 | 934 / 777 | 1,284 / 1,306 | 1,009 / 233 | 95 / 76 |
| Exact Match | 240 | 2,642 / 1,107 | 5,408 / 5,227 | 751 / 752 | 122 / 118 |
| JOIN 3-table | 6 | 874 / 103 | 330 / 224 | 22 / 12 | 7 / 36 |
| JOIN + ORDER BY | 4 | 1,243 / 213 | 199 / 199 | 36 / 13 | 5 / 5 |
| JOIN 5-table | 2 | 97 / 52 | 95 / 103 | 26 / 18 | 46 / 3 |
| JOIN + GROUP BY | 2 | 1,051 / 743 | 758 / 923 | 15,594 / 16,004 | 29,660 / 27,406 |
| Basic SELECT | 48 | 1,429 / 101 | 225 / 227 | 2,645 / 2,405 | 1,158 / 234 |
| JOIN 4-table | 1 | 311 / 26 | 95 / 73 | 6 / 4 | 19 / 3 |
| IN / NOT IN | 14 | 291 / 300 | 373 / 379 | 8,424 / 8,335 | 4,593 / 4,663 |
| ORDER BY | 16 | 285 / 73 | 236 / 136 | 25 / 12 | 4 / 3 |
| HAVING | 16 | 34 / 33 | 223 / 163 | 16,710 / 17,504 | 6,308 / 6,250 |
| Projection | 28 | 26 / 24 | 70 / 76 | 28 / 62 | 3 / 2 |
| DISTINCT | 5 | 34 / 29 | 53 / 50 | 5,069 / 4,685 | 4 / 4 |
| NULL Handling | 16 | 29 / 20 | 27 / 26 | 5,166 / 4,975 | 1,058 / 962 |
| Secondary Table | 6 | 3 / 2 | 17 / 11 | 1,333 / 1,059 | 435 / 127 |
| Nested/Object | 10 | 85 / 53 | 380 / 169 | — | — |
| Nested/Array | 30 | 553 / 483 | 473 / 407 | — | — |
| All categories | 3,551 | 186,738 / 120,505 | 164,341 / 161,590 | 1,204,521 / 1,207,568 | 507,540 / 496,809 |
Each cell is cold / warm total milliseconds; parallel figures are per client, so each run executes 14,204 queries in total. The two Nested categories query values held inside arrays and nested objects, a shape PostgreSQL and SQLite were not measured on, so those cells are empty rather than estimated.
Measured August 2026
TPC-C transactions
The benchmarks above measure reads. This one measures writes: the TPC-C order-entry mix over 4 warehouses, with 1,000 warm-up transactions, then 10,000 from a single client and 10,000 from 4 parallel clients, identical for every engine. InventDB runs with checkpoints on, so data is being persisted throughout.
| Engine | Mode | Single client tpstransactions/sec | 4 parallel clients tpstransactions/sec | Integrity |
|---|---|---|---|---|
| InventDB | in-process | 254.0 | 207.4 | exact accounting 11/11 |
| SQLite | in-process | 131.7 | 184.4 | passed |
| InventDB | client/server | 91.1 | 255.8 | exact accounting 11/11 |
| PostgreSQL | client/server | 134.7 | 365.4 | passed |
Every engine completed 10,000 of 10,000 transactions in both modes. InventDB also verifies exact transaction accounting: 11 balance identities that must hold to the cent across warehouses, districts and customers, recorded as 11/11. Checkpoints ran every 300 ms in both modes, more aggressive than the server's 5-second default, so the persistence pipeline is exercised throughout rather than skipped.
How it compares
Built-in capabilities, side by side
A comparison of built-in capabilities: what ships in the box, without bolting on extra services. It is not a performance or pricing comparison. Verified July 2026 against official docs and release notes.
| Capability | InventDB | PostgreSQL 18 | MongoDB 8 (Community) | SQLite |
|---|---|---|---|---|
| Data model | ||||
| Schema-free JSON documents | Built in | JSONB | Yes | JSON1 |
| SQL query language | Built in | Yes | — (MQL) | Yes |
| Nested objects & arrays | Built in | JSONB | Yes | JSON1 |
| Reliability | ||||
| Full ACID transactions | Built in | Yes | Yes | Yes |
| Write-ahead log (WAL) | Built in | Yes | Yes (journal) | Yes |
| Self-healing corruption recovery | Built in | — (manual) | — (manual) | — (manual) |
| Security & encryption | ||||
| Encryption at rest | Built in | — (disk/TDE) | Enterprise | Add-on (SEE) |
| Row-level value encryption | Built in | Add-on (pgcrypto) | Yes (client keys) | Add-on (SEE) |
| Encrypted, queryable indexes | Built in | — | Yes (Queryable Enc.) | — |
| Database-managed rotatable keys | Built in | — (external KMS) | — (customer-managed) | — |
| Role-based access control | Built in | Yes | Yes | — |
| Indexing & performance | ||||
| Automatic indexing | Built in | — (manual) | — (manual) | — (manual) |
| Built-in key-value cache | Built in | — | — | — |
| Search | ||||
| Exact-match search | Built in | Yes | Yes | Yes |
| Full-text (keyword) search | Built in | Yes | Yes | Yes (FTS5) |
| Fuzzy / typo-tolerant search | Built in | Add-on (pg_trgm) | Add-on (Atlas Search) | — |
| Semantic / vector search | Built in | Extension (pgvector) | Add-on (mongot) | Extension (sqlite-vec) |
| Files & documents | ||||
| Encrypted file storage | Built in | — | — (GridFS unencrypted) | — |
| Text extraction, 25+ formats | Built in | — | — | — |
| Built-in OCR (image/PDF → text) | Built in | — | — | — |
| File version history | Built in | — | — | — |
| Built-in AI agent | ||||
| Natural-language Q&A | Built in | Add-on (SQL-gen only) | — | — |
| Multi-step analysis & reports | Built in | — | — | — |
| Natural-language data edits | Built in | — | — | — |
| Scheduled reports | Built in | — | — | — |
| Operations & deployment | ||||
| Single binary, zero dependencies | Built in | — (server) | — (server + mongot) | Yes |
| Driverless HTTP / REST API | Built in | Add-on (PostgREST) | Add-on (Data API) | — |
| Cross-platform (Win/Linux/macOS) | Yes | Yes | Yes | Yes |
Verified July 2026 against official docs and release notes; capabilities move fast, so confirm with each vendor.
The rig
One machine per engine
All three are AWS Graviton t4g.large instances: 2 vCPU, 8 GiB RAM, data on an EBS volume, the same shape as the Business Small tier customers run on, and not on a workstation with sixteen cores and a warm file cache.
| Machine | Engine | Configuration |
|---|---|---|
| InventDB rig | InventDB, run both in-process and client/server | AES-256 encryption on throughout. The columnar cache, the document cache and memory-mapped sealed segments are all on: the shipping default, each sized by the server from the memory the machine reports rather than set by hand. |
| PostgreSQL rig | PostgreSQL 18.4, client/server only | synchronous_commit=on, shared_buffers=2GB, an index on every column. |
| SQLite rig | SQLite, in-process only | WAL with synchronous=FULL, 128 MB page cache, 4 GB mmap, an index on every column. |
PostgreSQL has no in-process mode and SQLite has no server mode, so InventDB is measured both ways and compared with each on its own terms: in-process against SQLite, client/server against PostgreSQL. Comparing an embedded engine against a networked one and calling the difference a win is the easiest way to publish a number that means nothing.
Every releasable build
What runs, every time
The same benchmark legs, on the same 10-million-record dataset restored from a fixed snapshot, never regenerated, so the data cannot drift between releases.
| Leg | What it is | How it is run |
|---|---|---|
| Full SQL battery | 3,551 queries across 28 categories: joins, aggregates, ordering, pagination, LIKE, nested paths | single-threaded and four-thread, in-process and client/server |
| 143-query shared set | The subset every engine can answer in its own dialect, for a like-for-like comparison | single-threaded and four-thread, in-process and client/server |
| TPC-C | The transaction benchmark (NewOrder, Payment, OrderStatus, Delivery, StockLevel) with exact accounting checks | sequential and four-thread, in-process and client/server |
Alongside the benchmarks, every releasable build runs the functional suites: smoke, regression, the QA campaign, the API harness and the engine's own test batteries. A build that is fast and wrong is not a release candidate.
Method
How the numbers are kept honest
Most of the work in a benchmark is not running it. It is making sure the thing measured is the thing you think was measured.
| Rule | Why it exists |
|---|---|
| Row counts are cross-checked between engines | Every query's result count is compared across all three. An engine that quietly returns fewer rows fails the leg rather than winning it. |
| Correctness tests check the answer rather than the row count | A wrong top-100 still has 100 rows, and a wrong COUNT still returns one row. Ordered queries are checked against the true minimum and maximum, and against the number of qualifying rows beyond the last one returned. |
| Every engine gets the same schema work | InventDB indexes every property by design, so the comparators are given an index on every column too. A primary-key-only schema would measure a different amount of write work. |
| Durability is matched | PostgreSQL runs synchronous_commit=on; SQLite runs WAL with synchronous=FULL. No engine may acknowledge a commit the others are still flushing. |
| Benchmark harnesses are matched too | The TPC-C harnesses were single-warehouse by construction, which turns the benchmark into a single-row contention test. All three now take the same scale and thread-routing settings. |
| A result is not believed until it repeats | An outlier is re-run, and a suspected regression is re-measured against a control build in the same environment before it is attributed to any change. |
| Reverted work is published too | The release notes record optimisations that were measured and thrown away, two of which made a category several hundred times slower. The measurements are the useful part. |
Methodology
How we ran it
The setup, in full
Two platforms are published on this page. The Linux · ARM tab is the reference: three dedicated Graviton machines, one per engine, identical spec, the same 10M-record dataset; see how we test. The Windows tab is the same suites on a single workstation with four cores. Different hardware, so the two are never mixed and never totalled together.
10M records, encryption on, and the engine in its shipping configuration: the columnar cache, the document cache and memory-mapped reads of sealed files are all on, each sized by the server from the memory the machine reports. Earlier releases were measured with those caches switched off; the two are not comparable, and only the current configuration is published here. Each suite runs twice: with a single client (one connection, queries in sequence) and with 4 parallel clients each running the whole battery against one shared database. Those labels count callers rather than internal threads. Cold is a query's first execution on an established connection; warm is a repeat. Every server is warmed before its leg. The two suites, 143 queries (18 categories) and the 3,551-query battery (28 categories), are never totalled together. PostgreSQL 18 and SQLite ran over the same data, driven the same way.
How PostgreSQL was configured. 23 indexes, covering the same columns InventDB indexes plus every join key; work_mem 256 MB, maintenance_work_mem 1 GB, and ANALYZE run on all four tables before measuring. shared_buffers was left at its default. Where PostgreSQL has the better index for a query it wins, and those categories are published as measured, Exact Match and Range among them.
The operating system favours InventDB here. These runs are on Windows, where PostgreSQL's process-per-connection model costs more than it does on Linux. The effect is largest in the 4-parallel-client leg, so treat the parallel PostgreSQL figures as a Windows result rather than a ceiling. The Linux results are measured separately and published in the Linux · ARM tab.
Common questions
How was this benchmark run?
On three dedicated ARM machines, one per engine, with encryption on and the engine in its shipping configuration, over a 10M-record dataset, in two legs: a single client and 4 parallel clients running the same battery at once against one shared database. Cold is a query's first execution on an established connection; warm is a repeat. Every server is warmed beforehand. PostgreSQL 18 and SQLite were run over the same data, driven the same way.
How do the InventDB and PostgreSQL numbers compare?
On the 143-query shared set, single client: InventDB 117,669 ms cold / 22,247 ms warm; PostgreSQL 18 139,807 / 139,209. On the 3,551-query battery, single client warm: InventDB 159,103 ms in-process and 166,872 ms client/server; PostgreSQL 136,915 ms client/server. PostgreSQL is ahead on the 3,551-query battery and behind on the 143-query set; both are published as measured. Per-category figures are in the tables above.
How do the InventDB and SQLite numbers compare?
On the 143-query shared set, single client: InventDB 117,669 ms cold / 22,247 ms warm; SQLite 358,746 / 357,636. Per-category figures are in the table above.
Do the numbers vary by category?
Yes, substantially. Category totals span several orders of magnitude across all three engines, and the ordering between them differs by category. Every category is published in the tables above, including those where InventDB records the higher number.
Which battery do these numbers come from?
Two separate suites are published: a 143-query shared set across 18 categories, and a 3,551-query full SQL battery across 28 categories. They are different suites and are never totalled together.
Can I reproduce these numbers myself?
Yes. Create your own encrypted database, load your data and run whichever queries you care about: same SQL, same engine. The capability comparison further up is a separate matter: public sources as of July 2026, describing what ships built in rather than speed.
Run your own numbers.
Create your own encrypted database, load your data and measure it yourself. The same SQL and API apply from a few thousand rows to 250 million records.