Skip to content
Opensource internals
  • Posts

Performance

How ClickHouse JIT-Compiles Scalar Expressions with LLVM

Oct 21, 2026 17 min read Jay Hubbert

Every columnar database pays the same tax: a SELECT is not a loop over rows, it is a graph of actions, and every action dispatches through a virtual call per block. The block is …

ClickhousePerformanceInternalsJitLlvm

Read more →

How ClickHouse Marks Empty Hash Table Cells With Zeroed Memory

Oct 21, 2026 23 min read Jay Hubbert

Every GROUP BY in ClickHouse is a hash table. The table has to hold millions of keys, be probed once per input row, and be resized while it is being filled — all while the query is …

ClickhouseInternalsHash tablePerformanceMemory

Read more →

How ClickHouse Merges Columns One at a Time: the Vertical Merge Algorithm

Oct 21, 2026 19 min read Jay Hubbert

Every MergeTree table is a pile of immutable parts. Every part is a pile of immutable columns. Background merges take a contiguous range of parts and rewrite them as one bigger …

ClickhousePerformanceInternalsMerge treeStorage engine

Read more →

How ClickHouse Packs Short Strings Into Hash Table Keys

Oct 21, 2026 13 min read Jay Hubbert

Strings are the most common GROUP BY key in practice. They are also the worst case for a hash table: a std::string in a cell means one heap allocation per distinct key, and a …

ClickhouseInternalsHash tableStringsPerformance

Read more →

How ClickHouse Plans Distributed Queries with Cascades

Oct 21, 2026 21 min read Jay Hubbert

A single-node query plan has one obvious shape: read the table, filter, aggregate, sort. A distributed query does not. The same SELECT can be executed as a gather everything to the …

ClickhousePerformanceInternalsQuery planningDistributed

Read more →

← Newer Page 2 of 8 Older →

© 2026 Jay Hubbert · Built with Hugo 0.168.0

RSS ·