A query that takes four minutes on your production Postgres finishes in under a second on a warehouse holding the same data. The hardware is comparable. The query is identical. The difference is which direction the data is written to disk.
Row-oriented storage keeps each record's fields adjacent — everything about customer 4,192 sits together. Columnar storage keeps each field's values adjacent — every customer's signup date sits together. Both are reasonable. They are optimised for opposite questions.
What changed in 2026
- Open table formats displaced proprietary ones. Columnar files plus an open metadata layer became the default way to store analytical data, which decoupled storage from whichever engine queries it.
- Row and column stopped being an either/or. Transactional databases gained columnar extensions and analytical engines gained faster point lookups, narrowing a gap that used to force an architectural choice.
- Vectorised execution became the expected companion. Columnar layout enables processing values in batches through CPU vector instructions, and engines that do not exploit that leave most of the benefit unclaimed.
- Object storage became the default substrate. Columnar files on cheap object storage, queried directly, replaced a great deal of dedicated warehouse infrastructure.
Row vs columnar
|
Row store |
Columnar store |
| Layout |
All fields of a record together |
All values of a field together |
| Fast at |
Fetching or writing whole records |
Scanning a few columns over many rows |
| Slow at |
Wide scans over few columns |
Single-row reads and updates |
| Compression |
Modest — mixed types adjacent |
Strong — uniform types adjacent |
| Typical use |
Application databases |
Analytics, reporting, warehouses |
| Write pattern |
Frequent small updates |
Bulk append |
The intuition worth holding: a query's cost is roughly what it reads, not what it returns. SELECT AVG(amount) FROM orders over a 200-column table reads one column in a columnar store and all 200 in a row store. That is not a tuning difference, it is a different amount of work.
Why compression works so much better
This is the part that surprises people, and it compounds with the first benefit rather than merely adding to it.
In a row store, adjacent bytes are a name, then a timestamp, then a boolean, then a float. Mixed types, mixed ranges, little repetition — general-purpose compression has little to exploit.
In a columnar store, adjacent bytes are ten thousand consecutive timestamps, or ten thousand values from a set of five country codes. Now specialised encodings apply. Run-length encoding collapses repeated values. Dictionary encoding replaces repeated strings with small integers. Delta encoding stores differences between sorted numbers rather than the numbers. A sorted timestamp column can compress by an order of magnitude or more.
The effect compounds because compressed data is less data to read from disk and less to move into CPU cache. Many engines operate directly on the encoded representation — filtering dictionary-encoded values by comparing integers rather than strings — so decompression is often partially avoided rather than merely amortised.
Sort order matters enormously here and is the most underused lever available. Sorting by a low-cardinality column before writing dramatically improves both compression and the effectiveness of row-group skipping.
Where it falls down
Fetching one complete row means reading from every column's storage — the exact inverse of the analytical case, and columnar layout is genuinely bad at it. Updating one field of one row can require rewriting a whole block, since columnar files are typically immutable.
This is why columnar storage did not simply replace row storage. An application serving user profiles does point lookups and small updates constantly; that is a row store's home ground. The industry answer has been to run both — a transactional row store for the application, columnar storage for analytics, and a pipeline moving data between them. Data lake vs data warehouse covers how those pieces usually fit together.
Modern formats hedge by organising data into row groups with columnar layout inside each. Statistics per group — minimum, maximum, null counts — let a query skip entire groups without reading them, which recovers some point-lookup ability. It is a genuine improvement and still not a substitute for an index on a transactional table.
Common mistakes
- Using it for transactional workloads. Frequent single-row updates against columnar storage is the wrong tool applied with conviction.
SELECT * in an analytical query. It discards the entire benefit by asking for every column.
- Ignoring sort order at write time. Unsorted data compresses worse and skips fewer row groups. This is often the largest single win available.
- Very small files. Metadata overhead and lost compression context. Small files are the most common cause of a slow query layer over object storage.
- Row groups sized badly. Too small loses compression, too large defeats skipping.
- Expecting an index to fix it. Columnar engines rely on scanning efficiently and skipping blocks, not on the index structures a row store uses.
FAQ
Is Parquet a database?
No — it is a file format. Engines read and write it; the format itself stores columnar data with per-row-group statistics. Storing data in an open format rather than an engine's internal one is what lets several query engines read the same files.
Can Postgres do columnar?
Through extensions and adjacent tooling, yes, and it can be a good middle path when your analytical volume does not justify separate infrastructure. Beyond a certain scale a purpose-built engine wins clearly. Postgres 18 features covers what the core has been adding.
Does columnar storage help with joins?
Somewhat — reading fewer columns means less data to join. But join strategy, data distribution, and shuffle cost usually dominate, and none of those are storage-layout questions.
How does this relate to a lakehouse?
A lakehouse is essentially columnar files on object storage plus a metadata layer providing transactions and schema evolution. Columnar storage is the substrate — lakehouse architecture explained covers what gets built on top.
Where to go next
For where columnar storage sits in a broader data platform, read data lake vs data warehouse and lakehouse architecture explained. For the row-store side and what it optimises instead, database indexing explained.