Row stores win when queries read or change whole rows by key under heavy concurrency; column stores win when queries scan many rows and few columns and data arrives in batches. Most platforms keep both, as BookNest does.
| Option | Storage model | Licence | Fits |
|---|---|---|---|
| PostgreSQL 1,289 heap | Row | PostgreSQL License | OLTP, moderate analytics |
| pg_duckdb extension | DuckDB 61,228 engine inside PostgreSQL | MIT | Analytics beside OLTP data |
| Citus columnar | Columnar table access method | AGPL-3.0 | Compressed append-only tables |
| DuckDB | Columnar, in-process | MIT | One machine, files, notebooks |
| ClickHouse 29,491 | Columnar server (MergeTree) | Apache 2.0 | High-concurrency real-time analytics |
| Parquet 129 on object storage | Columnar files | Apache 2.0 | Lakehouses, many engines (Lakehouses, Data Quality and Governance) |
pg_duckdb (https://github.com/duckdb/pg_duckdb 3,256 ) (v1.1.1, PostgreSQL 14 to 18) runs DuckDB's engine on PostgreSQL tables and Parquet files; Citus (https://github.com/citusdata/citus 12,796 ) 14.1 adds USING columnar tables. Both avoid a second database but share the server's CPU with the app. PostgreSQL 18 for Analytics to Views, Partitions, Parallelism push PostgreSQL's row store as far as it goes; DuckDB: In-Process OLAP to DuckDB Extensions vs Postgres do the same for DuckDB.