Skip to content
Opensource internals
  • Posts

Internals

How ClickHouse Evaluates IN with Hash Sets

Oct 21, 2026 20 min read Jay Hubbert

x IN (1, 2, 3) looks like a comparison. x IN (SELECT user_id FROM logins WHERE …) looks like a join. Under the hood both become the same thing: a hash set, built once, probed once …

ClickhousePerformanceInternalsHash tableSet

Read more →

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 →

← Newer Page 2 of 24 Older →

© 2026 Jay Hubbert · Built with Hugo 0.168.0

RSS ·