<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/"><channel><title>Overview on Opensource internals</title><link>https://articles.9j.nz/tags/overview/</link><description>Posts filed under Overview on Opensource internals.</description><generator>Hugo</generator><language>en-US</language><managingEditor>Jay Hubbert</managingEditor><lastBuildDate>Wed, 21 Oct 2026 09:17:00 +0000</lastBuildDate><atom:link href="https://articles.9j.nz/tags/overview/index.xml" rel="self" type="application/rss+xml"/><item><title>A Tour of DataFusion's Physical Operators: The Ten That Matter and the Trick Each One Uses</title><link>https://articles.9j.nz/posts/a-tour-of-datafusions-physical-operators/</link><pubDate>Wed, 21 Oct 2026 09:17:00 +0000</pubDate><dc:creator>Jay Hubbert</dc:creator><guid isPermaLink="true">https://articles.9j.nz/posts/a-tour-of-datafusions-physical-operators/</guid><category>datafusion</category><category>execution</category><category>performance</category><category>internals</category><category>overview</category><description>A guided tour of the physical operators that show up in almost every DataFusion plan, and the one clever idea each of them is built around.</description><content:encoded>&lt;blockquote&gt;&#10;&lt;p&gt;&lt;strong&gt;TL;DR:&lt;/strong&gt; &lt;code&gt;EXPLAIN&lt;/code&gt; a DataFusion query and you will see a dozen node&#10;names. Most of them are one of ten operators, and each of those ten is&#10;built around a single idea. This is a tour of that list: what the&#10;operator does, the trick it is built on, and where its own article in&#10;this series lives.&lt;/p&gt;&#10;&lt;/blockquote&gt;&#10;&lt;p&gt;&lt;code&gt;EXPLAIN&lt;/code&gt; output is a good way to learn an engine, and a bad way to&#10;understand it. The node names are opaque and the tree looks like it was&#10;assembled by a committee.&lt;/p&gt;&#10;&lt;p&gt;It was not. Every node in there is one of a small set of operators, and&#10;each of those has a specific idea at its core. Here is the tour.&lt;/p&gt;&#10;&lt;h2 id="1-datasourceexec--the-scan"&gt;1. &lt;code&gt;DataSourceExec&lt;/code&gt; — the scan&lt;/h2&gt;&#10;&lt;p&gt;The leaf. It knows how to turn a &lt;code&gt;FileScanConfig&lt;/code&gt; into a stream of&#10;batches, and it is where the file-format-specific work happens:&#10;listing the object store, reading the Parquet footer, evaluating&#10;pruning predicates, decoding pages.&lt;/p&gt;&#10;&lt;p&gt;&lt;strong&gt;The trick:&lt;/strong&gt; &lt;em&gt;decide what to read before reading it&lt;/em&gt;. The footer is&#10;read first, and it contains enough statistics to skip entire row groups&#10;and entire files. The newer &lt;em&gt;push decoder&lt;/em&gt; goes further: it interleaves&#10;byte-range fetches with decoding, so a filter that tightens at runtime&#10;can still prune the row groups that have not been fetched yet.&lt;/p&gt;&#10;&lt;h2 id="2-filterexec--the-filter"&gt;2. &lt;code&gt;FilterExec&lt;/code&gt; — the filter&lt;/h2&gt;&#10;&lt;p&gt;Evaluates a boolean predicate against each batch and emits the rows that&#10;pass.&lt;/p&gt;&#10;&lt;p&gt;&lt;strong&gt;The trick:&lt;/strong&gt; the filter is &lt;em&gt;pushable&lt;/em&gt;. It offers its predicate to the&#10;child, and the child may take it — entirely, partially, or not at all.&#10;The Parquet scan takes it partially: it evaluates the predicate against&#10;row-group statistics to skip data, &lt;em&gt;and&lt;/em&gt; keeps a residual filter to&#10;guarantee correctness. The two-phase negotiation is&#10;&lt;code&gt;gather_filters_for_pushdown&lt;/code&gt; / &lt;code&gt;handle_child_pushdown_result&lt;/code&gt;.&lt;/p&gt;&#10;&lt;h2 id="3-projectionexec--the-projection"&gt;3. &lt;code&gt;ProjectionExec&lt;/code&gt; — the projection&lt;/h2&gt;&#10;&lt;p&gt;Selects and computes output columns.&lt;/p&gt;&#10;&lt;p&gt;&lt;strong&gt;The trick:&lt;/strong&gt; it is &lt;em&gt;foldable&lt;/em&gt;. &lt;code&gt;try_swapping_with_projection&lt;/code&gt; lets a&#10;projection be absorbed into the operator below, so the scan reads only&#10;the columns that survive — and the projection node disappears from the&#10;plan entirely. There is even an &lt;em&gt;embedded&lt;/em&gt; variant, where the projection&#10;becomes a &lt;code&gt;Vec&amp;lt;usize&amp;gt;&lt;/code&gt; inside the join, so the join never materialises&#10;the dropped columns at all.&lt;/p&gt;&#10;&lt;h2 id="4-repartitionexec--the-shuffle"&gt;4. &lt;code&gt;RepartitionExec&lt;/code&gt; — the shuffle&lt;/h2&gt;&#10;&lt;p&gt;Splits the input into N partitions, either round-robin (no coordination)&#10;or by hash (both sides agree without talking).&lt;/p&gt;&#10;&lt;p&gt;&lt;strong&gt;The trick:&lt;/strong&gt; &lt;em&gt;slicing, not copying&lt;/em&gt;. A batch is routed by computing&#10;row indices per partition, doing &lt;strong&gt;one&lt;/strong&gt; &lt;code&gt;take&lt;/code&gt; per column, and handing&#10;out &lt;code&gt;RecordBatch::slice&lt;/code&gt; views. Round-robin skips the &lt;code&gt;take&lt;/code&gt; entirely.&#10;The &lt;code&gt;StrengthReducedU64&lt;/code&gt; trick replaces a &lt;code&gt;%&lt;/code&gt; with a mask or a&#10;reciprocal-multiply, because division is expensive and the modulus is&#10;constant.&lt;/p&gt;&#10;&lt;h2 id="5-hashjoinexec--the-equi-join"&gt;5. &lt;code&gt;HashJoinExec&lt;/code&gt; — the equi-join&lt;/h2&gt;&#10;&lt;p&gt;The workhorse. Builds a hash table over the smaller side, probes it with&#10;the larger.&lt;/p&gt;&#10;&lt;p&gt;&lt;strong&gt;The trick:&lt;/strong&gt; &lt;em&gt;the build side is reused three times&lt;/em&gt;. It is the hash&#10;table, it is the payload, and it is the &lt;strong&gt;dynamic filter&lt;/strong&gt; published to&#10;the probe side — so the probe side can skip rows that cannot match,&#10;using a membership test against the &lt;em&gt;same&lt;/em&gt; table. There is also a&#10;perfect-hash variant: when the build key is a dense integer, the hash&#10;table is replaced by a flat array indexed by the key.&lt;/p&gt;&#10;&lt;h2 id="6-sortexec--the-sort"&gt;6. &lt;code&gt;SortExec&lt;/code&gt; — the sort&lt;/h2&gt;&#10;&lt;p&gt;&lt;strong&gt;The trick:&lt;/strong&gt; &lt;em&gt;two modes&lt;/em&gt;. Below a threshold, everything is concatenated&#10;and sorted in one go — no merge at all. Above it, the input is sorted&#10;into runs and merged, with the runs &lt;em&gt;coalesced&lt;/em&gt; first when the sort key&#10;is a single column, because then the merge&amp;rsquo;s per-stream overhead&#10;dominates its per-comparison cost.&lt;/p&gt;&#10;&lt;h2 id="7-sortpreservingmergeexec--the-merge"&gt;7. &lt;code&gt;SortPreservingMergeExec&lt;/code&gt; — the merge&lt;/h2&gt;&#10;&lt;p&gt;Merges N sorted streams into one sorted stream.&lt;/p&gt;&#10;&lt;p&gt;&lt;strong&gt;The trick:&lt;/strong&gt; it does not sort. It keeps a cursor per stream and always&#10;takes the smallest head. When the streams are sorted &lt;em&gt;ranges&lt;/em&gt; (which the&#10;range-partitioning machinery produces), the merge is a simple&#10;concatenation. And when there are too many runs to merge at once, the&#10;&lt;em&gt;multi-level merge&lt;/em&gt; spills intermediate results and repeats.&lt;/p&gt;&#10;&lt;h2 id="8-aggregateexec--the-aggregation"&gt;8. &lt;code&gt;AggregateExec&lt;/code&gt; — the aggregation&lt;/h2&gt;&#10;&lt;p&gt;Groups and aggregates.&lt;/p&gt;&#10;&lt;p&gt;&lt;strong&gt;The trick:&lt;/strong&gt; &lt;em&gt;the accumulator is a state machine&lt;/em&gt;, split into&#10;&lt;code&gt;update_batch&lt;/code&gt; / &lt;code&gt;state&lt;/code&gt; / &lt;code&gt;merge_batch&lt;/code&gt; / &lt;code&gt;evaluate&lt;/code&gt;, which is what&#10;makes the partial/final two-phase split possible. And the group table&#10;itself can be skipped entirely when the input is already sorted by the&#10;grouping key — the &lt;em&gt;group clustering&lt;/em&gt; optimisation replaces the hash&#10;table with Arrow&amp;rsquo;s &lt;code&gt;partition&lt;/code&gt; kernel.&lt;/p&gt;&#10;&lt;h2 id="9-windowaggexec--the-window-function"&gt;9. &lt;code&gt;WindowAggExec&lt;/code&gt; — the window function&lt;/h2&gt;&#10;&lt;p&gt;&lt;strong&gt;The trick:&lt;/strong&gt; &lt;em&gt;the frame is a state machine over a sorted stream&lt;/em&gt;. A&#10;&lt;code&gt;ROWS&lt;/code&gt; frame is stateless (you know the offset); a &lt;code&gt;RANGE&lt;/code&gt; frame needs&#10;state, because &amp;ldquo;the current tie group&amp;rdquo; has to be tracked. And the&#10;operator &lt;em&gt;declares&lt;/em&gt; that it needs its input sorted, so the optimizer&#10;inserts a sort if there is not one.&lt;/p&gt;&#10;&lt;h2 id="10-coalescepartitionsexec--the-fan-in"&gt;10. &lt;code&gt;CoalescePartitionsExec&lt;/code&gt; — the fan-in&lt;/h2&gt;&#10;&lt;p&gt;Merges N partition streams into one.&lt;/p&gt;&#10;&lt;p&gt;&lt;strong&gt;The trick:&lt;/strong&gt; it is not a computation. It is a &lt;em&gt;promise&lt;/em&gt; — &amp;ldquo;the plan&#10;below has N partitions, but the caller wants one stream&amp;rdquo;. Which is what&#10;makes &lt;code&gt;execute_stream&lt;/code&gt; on a multi-partition plan possible without&#10;pushing fan-in into user code.&lt;/p&gt;&#10;&lt;h2 id="the-ones-you-will-also-see"&gt;The ones you will also see&lt;/h2&gt;&#10;&lt;p&gt;A few more, for completeness:&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;code&gt;GlobalLimitExec&lt;/code&gt; / &lt;code&gt;LocalLimitExec&lt;/code&gt; — the limit, split so that the&#10;global one can be a barrier.&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;UnionExec&lt;/code&gt; — the union of N plans.&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;UnnestExec&lt;/code&gt; — expanding a list column into rows.&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;ScalarSubqueryExec&lt;/code&gt; — evaluating a subquery once and broadcasting the&#10;result.&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;CooperativeExec&lt;/code&gt; — the budget that keeps a stream from hogging a&#10;worker.&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;AnalyzeExec&lt;/code&gt; — the &lt;code&gt;EXPLAIN ANALYZE&lt;/code&gt; wrapper.&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;BufferExec&lt;/code&gt; — decoupling a fast producer from a slow consumer.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="how-they-compose"&gt;How they compose&lt;/h2&gt;&#10;&lt;p&gt;The interesting part is not the operators individually but how they&#10;&lt;em&gt;negotiate&lt;/em&gt;. A &lt;code&gt;HashJoinExec&lt;/code&gt; says &amp;ldquo;I need hash-partitioned input on the&#10;join key&amp;rdquo;. A &lt;code&gt;RepartitionExec&lt;/code&gt; says &amp;ldquo;I can give you that&amp;rdquo;. The optimizer&#10;inserts the second between the first and whatever is below it, and if&#10;the input already satisfies the requirement, it inserts nothing.&lt;/p&gt;&#10;&lt;p&gt;The same negotiation happens for ordering (a &lt;code&gt;SortExec&lt;/code&gt; asks for sorted&#10;input and is deleted if the input is already sorted), for limits (a&#10;&lt;code&gt;SortExec&lt;/code&gt; can absorb a &lt;code&gt;LIMIT&lt;/code&gt; and stop early), and for filters (a&#10;&lt;code&gt;FilterExec&lt;/code&gt; pushes its predicate down and keeps a residual).&lt;/p&gt;&#10;&lt;p&gt;Which is why the plan you get is not the plan you asked for, and why&#10;&lt;code&gt;EXPLAIN&lt;/code&gt; is worth reading.&lt;/p&gt;&#10;&lt;h2 id="why-it-matters"&gt;Why it matters&lt;/h2&gt;&#10;&lt;p&gt;DataFusion&amp;rsquo;s operator set is small — a few dozen types — and each one&#10;is a well-known idea implemented with unusual care. The parts that&#10;surprise you are all the same shape:&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;a &lt;em&gt;statistical&lt;/em&gt; fact (min/max, hash, count) used to avoid work rather&#10;than to do work;&lt;/li&gt;&#10;&lt;li&gt;an &lt;em&gt;asymmetry&lt;/em&gt; exploited (the build side is also the filter; the&#10;probe side is also the producer of the sort);&lt;/li&gt;&#10;&lt;li&gt;a &lt;em&gt;boundary&lt;/em&gt; where the data is already in the right shape (a sorted&#10;input, a dense key range, a prefix group).&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p&gt;Once you learn to look for those three things, DataFusion&amp;rsquo;s plans stop&#10;looking like a committee&amp;rsquo;s compromise and start looking like a series&#10;of deliberate decisions.&lt;/p&gt;&#10;</content:encoded></item><item><title>A Tour of Polars' Internals: The Twelve Ideas That Explain the Engine</title><link>https://articles.9j.nz/posts/a-tour-of-polars-internals-the-twelve-ideas/</link><pubDate>Wed, 21 Oct 2026 09:00:00 +0000</pubDate><dc:creator>Jay Hubbert</dc:creator><guid isPermaLink="true">https://articles.9j.nz/posts/a-tour-of-polars-internals-the-twelve-ideas/</guid><category>polars</category><category>internals</category><category>performance</category><category>overview</category><category>architecture</category><description>A guided tour of the twelve ideas that make Polars fast — chunked columns, inline strings, arena-allocated expressions, morsel pipelines, hash shuffles — and where each one lives in the source.</description><content:encoded>&lt;blockquote&gt;&#10;&lt;p&gt;&lt;strong&gt;TL;DR:&lt;/strong&gt; Polars is a stack of small ideas, and almost every performance&#10;question you have about Polars can be answered by naming one of them.&#10;Chunks are the unit of parallelism. &lt;code&gt;View&lt;/code&gt; is the unit of string storage.&#10;The arena is the unit of expression allocation. The optimizer is a rewrite&#10;engine, not a cost model. The streaming engine is a pipeline of morsels.&#10;This is a tour of twelve of them, and where in the source tree each one&#10;lives.&lt;/p&gt;&#10;&lt;/blockquote&gt;&#10;&lt;p&gt;&lt;code&gt;pl.LazyFrame(...).explain()&lt;/code&gt; prints a plan, and the plan looks like a tree of&#10;node names — &lt;code&gt;SLICE&lt;/code&gt;, &lt;code&gt;SELECT&lt;/code&gt;, &lt;code&gt;SORT&lt;/code&gt;, &lt;code&gt;AGGREGATE&lt;/code&gt;. It reads like the output&#10;of a query planner in any other engine. It is not. Polars&amp;rsquo; plan is closer to a&#10;compilation unit: a tree that gets rewritten several times before a single&#10;byte of data moves, and then executed by one of two quite different runtimes.&lt;/p&gt;&#10;&lt;p&gt;The best way to learn the engine is to ignore the node names and ask, for&#10;each one, &lt;em&gt;what is the trick underneath it&lt;/em&gt;. Here is that list.&lt;/p&gt;&#10;&lt;h2 id="1-the-dsl-the-ir-and-the-fact-that-there-are-two-of-each"&gt;1. The DSL, the IR, and the fact that there are two of each&lt;/h2&gt;&#10;&lt;p&gt;The user-facing plan is &lt;code&gt;DslPlan&lt;/code&gt;, a tree of &lt;code&gt;Arc&amp;lt;DslPlan&amp;gt;&lt;/code&gt; nodes with&#10;&lt;code&gt;Expr&lt;/code&gt; leaves — user-level expressions, cheap to clone, awkward to analyze.&lt;/p&gt;&#10;&lt;div class="code-block"&gt;&#10; &lt;div class="code-block-head"&gt;&#10; &lt;span class="code-lang"&gt;rust&lt;/span&gt;&#10; &lt;button class="code-copy" type="button" data-copy&gt;Copy&lt;/button&gt;&#10; &lt;/div&gt;&#10; &lt;div class="code-block-body"&gt;&#10; &lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-rust" data-lang="rust"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// crates/polars-plan/src/dsl/plan.rs:32&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;pub&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;enum&lt;/span&gt; &lt;span class="nc"&gt;DslPlan&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="cp"&gt;#[cfg(feature = &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;python&amp;#34;&lt;/span&gt;&lt;span class="cp"&gt;)]&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;PythonScan&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;options&lt;/span&gt;: &lt;span class="nc"&gt;crate&lt;/span&gt;::&lt;span class="n"&gt;dsl&lt;/span&gt;::&lt;span class="n"&gt;python_dsl&lt;/span&gt;::&lt;span class="n"&gt;PythonOptionsDsl&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="sd"&gt;/// Filter on a boolean mask&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Filter&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;input&lt;/span&gt;: &lt;span class="nc"&gt;Arc&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;DslPlan&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;predicate&lt;/span&gt;: &lt;span class="nc"&gt;Expr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&#10; &lt;/div&gt;&#10;&lt;/div&gt;&#10;&lt;p&gt;&lt;code&gt;crates/polars-plan/src/dsl/plan.rs:32&lt;/code&gt;&lt;/p&gt;&#10;&lt;p&gt;The optimizer never touches that tree. It works on &lt;code&gt;IR&lt;/code&gt;, where every node&#10;lives in an arena and every expression is an &lt;code&gt;ExprIR&lt;/code&gt; — a resolved expression&#10;with a dtype, no user-facing sugar left in it.&lt;/p&gt;&#10;&lt;div class="code-block"&gt;&#10; &lt;div class="code-block-head"&gt;&#10; &lt;span class="code-lang"&gt;rust&lt;/span&gt;&#10; &lt;button class="code-copy" type="button" data-copy&gt;Copy&lt;/button&gt;&#10; &lt;/div&gt;&#10; &lt;div class="code-block-body"&gt;&#10; &lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-rust" data-lang="rust"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// crates/polars-plan/src/plans/ir/mod.rs:66&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Filter&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;input&lt;/span&gt;: &lt;span class="nc"&gt;Node&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;predicate&lt;/span&gt;: &lt;span class="nc"&gt;ExprIR&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&#10; &lt;/div&gt;&#10;&lt;/div&gt;&#10;&lt;p&gt;&lt;code&gt;crates/polars-plan/src/plans/ir/mod.rs:66&lt;/code&gt;&lt;/p&gt;&#10;&lt;p&gt;The split matters for a reason that is easy to miss: the DSL tree can be&#10;rebuilt cheaply and structurally, while the IR is what the &lt;em&gt;executors&lt;/em&gt; see.&#10;All the interesting analysis — predicate pushdown, projection pushdown,&#10;simplification, common-subplan elimination — happens on the IR, where the&#10;engine can ask questions like &amp;ldquo;is this expression already known to be&#10;non-null?&amp;rdquo; and get a real answer instead of a pattern match on syntax.&lt;/p&gt;&#10;&lt;p&gt;The arena itself is a &lt;code&gt;Vec&amp;lt;T&amp;gt;&lt;/code&gt; plus integer handles, which is about as cheap&#10;as it gets:&lt;/p&gt;&#10;&lt;div class="code-block"&gt;&#10; &lt;div class="code-block-head"&gt;&#10; &lt;span class="code-lang"&gt;rust&lt;/span&gt;&#10; &lt;button class="code-copy" type="button" data-copy&gt;Copy&lt;/button&gt;&#10; &lt;/div&gt;&#10; &lt;div class="code-block-body"&gt;&#10; &lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-rust" data-lang="rust"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// crates/polars-utils/src/arena.rs:38&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;pub&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="nc"&gt;Arena&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;version&lt;/span&gt;: &lt;span class="kt"&gt;u32&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;items&lt;/span&gt;: &lt;span class="nb"&gt;Vec&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&#10; &lt;/div&gt;&#10;&lt;/div&gt;&#10;&lt;p&gt;&lt;code&gt;crates/polars-utils/src/arena.rs:38&lt;/code&gt;&lt;/p&gt;&#10;&lt;p&gt;More on this in &lt;a href="https://articles.9j.nz/posts/how-polars-evaluates-expressions-in-an-arena/"&gt;Polars Evaluates Expressions in an&#10;Arena&lt;/a&gt;.&lt;/p&gt;&#10;&lt;h2 id="2-two-engines-and-a-switch-between-them"&gt;2. Two engines, and a switch between them&lt;/h2&gt;&#10;&lt;p&gt;&lt;code&gt;collect()&lt;/code&gt; does not pick an engine by measuring anything. It picks one by&#10;looking at flags:&lt;/p&gt;&#10;&lt;div class="code-block"&gt;&#10; &lt;div class="code-block-head"&gt;&#10; &lt;span class="code-lang"&gt;rust&lt;/span&gt;&#10; &lt;button class="code-copy" type="button" data-copy&gt;Copy&lt;/button&gt;&#10; &lt;/div&gt;&#10; &lt;div class="code-block-body"&gt;&#10; &lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-rust" data-lang="rust"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// crates/polars-lazy/src/frame/mod.rs:636&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;pub&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;collect_with_engine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;engine&lt;/span&gt;: &lt;span class="nc"&gt;Engine&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;-&amp;gt; &lt;span class="nc"&gt;PolarsResult&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;QueryResult&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;engine&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;match&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;engine&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Engine&lt;/span&gt;::&lt;span class="n"&gt;Streaming&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Engine&lt;/span&gt;::&lt;span class="n"&gt;Streaming&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;std&lt;/span&gt;::&lt;span class="n"&gt;env&lt;/span&gt;::&lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;POLARS_FORCE_STREAMING&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;as_deref&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;1&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Engine&lt;/span&gt;::&lt;span class="n"&gt;Streaming&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Engine&lt;/span&gt;::&lt;span class="n"&gt;Auto&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;opt_state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;eager&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Engine&lt;/span&gt;::&lt;span class="n"&gt;InMemory&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Engine&lt;/span&gt;::&lt;span class="n"&gt;Streaming&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&#10; &lt;/div&gt;&#10;&lt;/div&gt;&#10;&lt;p&gt;&lt;code&gt;crates/polars-lazy/src/frame/mod.rs:636&lt;/code&gt;&lt;/p&gt;&#10;&lt;p&gt;Both engines consume the &lt;em&gt;same&lt;/em&gt; optimized IR. The in-memory engine&#10;(&lt;code&gt;polars-mem-engine&lt;/code&gt;) builds a tree of &lt;code&gt;Box&amp;lt;dyn Executor&amp;gt;&lt;/code&gt; nodes and runs it&#10;depth-first with rayon fan-out; the streaming engine (&lt;code&gt;polars-stream&lt;/code&gt;) lowers&#10;the same IR into a &lt;em&gt;graph&lt;/em&gt; of nodes connected by pipes and runs it as a&#10;dataflow pipeline.&lt;/p&gt;&#10;&lt;p&gt;This is the single most interesting architectural fact in the codebase: the&#10;IR is the contract, and two very different runtimes honour it. A &lt;code&gt;filter&lt;/code&gt; is a&#10;closure in one and a pipe in the other.&lt;/p&gt;&#10;&lt;h2 id="3-chunks-are-the-unit-of-parallelism"&gt;3. Chunks are the unit of parallelism&lt;/h2&gt;&#10;&lt;p&gt;A &lt;code&gt;ChunkedArray&lt;/code&gt; is a vector of Arrow arrays plus a length. Every kernel&#10;walks it chunk by chunk, which means the chunk boundaries are simultaneously&#10;the unit of work, the unit of parallelism, and the granularity at which&#10;validity and offsets are tracked.&lt;/p&gt;&#10;&lt;div class="code-block"&gt;&#10; &lt;div class="code-block-head"&gt;&#10; &lt;span class="code-lang"&gt;rust&lt;/span&gt;&#10; &lt;button class="code-copy" type="button" data-copy&gt;Copy&lt;/button&gt;&#10; &lt;/div&gt;&#10; &lt;div class="code-block-body"&gt;&#10; &lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-rust" data-lang="rust"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// crates/polars-core/src/chunked_array/mod.rs:140&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;pub&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="nc"&gt;ChunkedArray&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;: &lt;span class="nc"&gt;PolarsDataType&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;pub&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;crate&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;field&lt;/span&gt;: &lt;span class="nc"&gt;Arc&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Field&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;pub&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;crate&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;chunks&lt;/span&gt;: &lt;span class="nb"&gt;Vec&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;ArrayRef&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;pub&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;crate&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;flags&lt;/span&gt;: &lt;span class="nc"&gt;StatisticsFlagsIM&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;length&lt;/span&gt;: &lt;span class="kt"&gt;usize&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;null_count&lt;/span&gt;: &lt;span class="kt"&gt;usize&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;_pd&lt;/span&gt;: &lt;span class="nc"&gt;std&lt;/span&gt;::&lt;span class="n"&gt;marker&lt;/span&gt;::&lt;span class="n"&gt;PhantomData&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&#10; &lt;/div&gt;&#10;&lt;/div&gt;&#10;&lt;p&gt;&lt;code&gt;crates/polars-core/src/chunked_array/mod.rs:140&lt;/code&gt;&lt;/p&gt;&#10;&lt;p&gt;Appending to a &lt;code&gt;ChunkedArray&lt;/code&gt; is free — you push another &lt;code&gt;ArrayRef&lt;/code&gt; into the&#10;&lt;code&gt;Vec&lt;/code&gt;. Random access costs an extra indirection, which is why the engine&#10;prefers chunk-local work and only pays for a global index when it has to.&lt;/p&gt;&#10;&lt;p&gt;Full treatment: &lt;a href="https://articles.9j.nz/posts/how-polars-chunks-columns-to-create-parallel-work/"&gt;Polars Chunks Its Columns So Parallelism Has Something to&#10;Eat&lt;/a&gt;.&lt;/p&gt;&#10;&lt;h2 id="4-view-a-string-that-fits-in-a-register"&gt;4. &lt;code&gt;View&lt;/code&gt;: a string that fits in a register&lt;/h2&gt;&#10;&lt;p&gt;The most copied type in the engine is not a &lt;code&gt;String&lt;/code&gt;. It is the 16-byte&#10;&lt;code&gt;View&lt;/code&gt;:&lt;/p&gt;&#10;&lt;div class="code-block"&gt;&#10; &lt;div class="code-block-head"&gt;&#10; &lt;span class="code-lang"&gt;rust&lt;/span&gt;&#10; &lt;button class="code-copy" type="button" data-copy&gt;Copy&lt;/button&gt;&#10; &lt;/div&gt;&#10; &lt;div class="code-block-body"&gt;&#10; &lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-rust" data-lang="rust"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// crates/polars-arrow/src/array/binview/view.rs:20&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cp"&gt;#[derive(Copy, Clone, Default)]&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cp"&gt;#[repr(C)]&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;pub&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="nc"&gt;View&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="sd"&gt;/// The length of the string/bytes.&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;pub&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;length&lt;/span&gt;: &lt;span class="kt"&gt;u32&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="sd"&gt;/// First 4 bytes of string/bytes data.&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;pub&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;prefix&lt;/span&gt;: &lt;span class="kt"&gt;u32&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="sd"&gt;/// The buffer index.&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;pub&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;buffer_idx&lt;/span&gt;: &lt;span class="kt"&gt;u32&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="sd"&gt;/// The offset into the buffer.&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;pub&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;offset&lt;/span&gt;: &lt;span class="kt"&gt;u32&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&#10; &lt;/div&gt;&#10;&lt;/div&gt;&#10;&lt;p&gt;&lt;code&gt;crates/polars-arrow/src/array/binview/view.rs:20&lt;/code&gt;&lt;/p&gt;&#10;&lt;p&gt;A string of twelve bytes or fewer is stored &lt;em&gt;inside&lt;/em&gt; the view. Anything&#10;longer spills into a shared buffer and the view keeps an index and an offset.&#10;Because the view is 16 bytes, comparing two of them is two integer compares&#10;before any string data is touched — the length rejects mismatches for free,&#10;and the four-byte prefix rejects most of the rest.&lt;/p&gt;&#10;&lt;p&gt;Full treatment: &lt;a href="https://articles.9j.nz/posts/how-polars-stores-short-strings-inline-in-16-bytes/"&gt;Polars Stores Short Strings Inline in 16 Bytes: The View&#10;Type&lt;/a&gt; and &lt;a href="https://articles.9j.nz/posts/how-polars-compares-strings-without-allocating/"&gt;Polars&#10;Compares Strings Without&#10;Allocating&lt;/a&gt;.&lt;/p&gt;&#10;&lt;h2 id="5-immutable-refcounted-buffers"&gt;5. Immutable, refcounted buffers&lt;/h2&gt;&#10;&lt;p&gt;There is no &lt;code&gt;Vec&amp;lt;u8&amp;gt;&lt;/code&gt; underneath a column. There is a &lt;code&gt;SharedStorage&amp;lt;T&amp;gt;&lt;/code&gt; with&#10;an &lt;code&gt;AtomicU64&lt;/code&gt; refcount and a hand-written vtable for the drop glue, and the&#10;only mutation path is copy-on-write through a &amp;ldquo;make this uniquely owned&amp;rdquo; step.&#10;That is what makes zero-copy sharing between a &lt;code&gt;DataFrame&lt;/code&gt;, a Python object&#10;and an Arrow C stream cheap: they all point at the same bytes.&lt;/p&gt;&#10;&lt;p&gt;Full treatment: &lt;a href="https://articles.9j.nz/posts/how-polars-buffers-are-immutable-and-refcounted/"&gt;Polars Buffers Are Immutable: The Refcounted Storage Behind&#10;Every Column&lt;/a&gt; and&#10;&lt;a href="https://articles.9j.nz/posts/how-polars-shares-columns-with-arc-instead-of-copying/"&gt;Polars Shares Columns Instead of Copying Them&lt;/a&gt;.&lt;/p&gt;&#10;&lt;h2 id="6-the-optimizer-is-a-rewrite-engine"&gt;6. The optimizer is a rewrite engine&lt;/h2&gt;&#10;&lt;p&gt;Polars&amp;rsquo; optimizer is a list of rewrite rules applied to fixed points. There&#10;is no cost model, no cardinality estimation driving plan choices, no&#10;&amp;ldquo;which join order is cheaper&amp;rdquo; search. A rule that fires changes the tree;&#10;the rules run again; if nothing changes, the plan is done.&lt;/p&gt;&#10;&lt;p&gt;That design has an obvious consequence — Polars will not reorder a join for&#10;you — and a less obvious one: because the rules are local and structural, they&#10;can be extremely aggressive about &lt;em&gt;shape&lt;/em&gt;. A &lt;code&gt;select&lt;/code&gt; that is really just a&#10;projection becomes a &lt;code&gt;SimpleProjection&lt;/code&gt;. A duplicated subplan becomes a&#10;&lt;code&gt;Cache&lt;/code&gt; node. A filter that is provably always-true disappears.&lt;/p&gt;&#10;&lt;p&gt;Full treatment: &lt;a href="https://articles.9j.nz/posts/how-polars-simplifies-the-expression-tree-before-running/"&gt;Polars Simplifies the Expression Tree Before It Runs&#10;Anything&lt;/a&gt;&#10;and &lt;a href="https://articles.9j.nz/posts/how-polars-eliminates-common-subexpressions-by-fingerprint/"&gt;Polars Kills Duplicate Subplans by&#10;Fingerprinting Them&lt;/a&gt;.&lt;/p&gt;&#10;&lt;h2 id="7-predicate-pushdown-ends-at-the-file-footer"&gt;7. Predicate pushdown ends at the file footer&lt;/h2&gt;&#10;&lt;p&gt;Pushdown in Polars is not one feature but three layers: the optimizer moves&#10;the filter into the scan node, the scan converts the predicate into&#10;per-row-group statistics checks, and the reader skips row groups whose&#10;min/max cannot satisfy it.&lt;/p&gt;&#10;&lt;p&gt;The conversion is the interesting part, because the filter has to be&#10;&lt;em&gt;compiled twice&lt;/em&gt;: once against the real columns, and once against a synthetic&#10;frame of &lt;code&gt;col_min&lt;/code&gt;/&lt;code&gt;col_max&lt;/code&gt; columns so the same expression code can be&#10;reused to test statistics.&lt;/p&gt;&#10;&lt;p&gt;Full treatment: &lt;a href="https://articles.9j.nz/posts/how-polars-pushes-predicates-into-the-parquet-scanner/"&gt;Polars Pushes Predicates Into the Parquet&#10;Scanner&lt;/a&gt; and&#10;&lt;a href="https://articles.9j.nz/posts/how-polars-prunes-parquet-row-groups-with-page-index-stats/"&gt;Polars Prunes Parquet Row Groups With Chunk&#10;Statistics&lt;/a&gt;.&lt;/p&gt;&#10;&lt;h2 id="8-group-keys-have-four-different-encodings"&gt;8. Group keys have four different encodings&lt;/h2&gt;&#10;&lt;p&gt;There is no single &amp;ldquo;group by&amp;rdquo; implementation. A single integer key groups by&#10;comparing integers. A single string key groups by dictionary codes. Multiple&#10;keys are encoded into &lt;em&gt;rows&lt;/em&gt; — fixed-width byte blobs with null bits — so&#10;that equality becomes a &lt;code&gt;memcmp&lt;/code&gt; and the hash is the hash of the row bytes.&lt;/p&gt;&#10;&lt;p&gt;Four encodings, four code paths, chosen by the shape of the key. The trick&#10;that makes the whole family fast is that the &lt;em&gt;encoding&lt;/em&gt; is also the&#10;&lt;em&gt;hashing&lt;/em&gt; input: there is no separate hash function per key type, there is&#10;one hash over the encoded bytes.&lt;/p&gt;&#10;&lt;p&gt;Full treatment: &lt;a href="https://articles.9j.nz/posts/how-polars-encodes-group-keys-as-rows-to-make-hashing-cheap/"&gt;Polars Encodes Group Keys as Rows to Make Hashing&#10;Cheap&lt;/a&gt;&#10;and &lt;a href="https://articles.9j.nz/posts/how-polars-groups-columns-so-one-pass-feeds-many-aggregations/"&gt;Polars Groups Columns So One Pass Feeds Many&#10;Aggregations&lt;/a&gt;.&lt;/p&gt;&#10;&lt;h2 id="9-sortedness-is-metadata-and-it-changes-the-algorithm"&gt;9. Sortedness is metadata, and it changes the algorithm&lt;/h2&gt;&#10;&lt;p&gt;Polars tracks whether a column is sorted as a flag on the chunked array, and&#10;the optimizer propagates that through the plan. A group-by on a sorted key&#10;does not hash: it walks runs. A merge join only accepts sorted inputs. A&#10;top-k on a sorted stream can stop early.&lt;/p&gt;&#10;&lt;p&gt;This is the cheapest possible form of query planning — a boolean that unlocks&#10;a completely different algorithm — and it is why &lt;code&gt;sort().group_by()&lt;/code&gt; can be&#10;dramatically faster than &lt;code&gt;group_by()&lt;/code&gt;.&lt;/p&gt;&#10;&lt;p&gt;Full treatment: &lt;a href="https://articles.9j.nz/posts/how-polars-aggregates-faster-when-the-keys-are-sorted/"&gt;Polars Aggregates Faster When the Keys Are Already&#10;Sorted&lt;/a&gt; and&#10;&lt;a href="https://articles.9j.nz/posts/how-polars-joins-two-tables-with-a-piecewise-merge-join/"&gt;Polars Joins Two Tables with a Piecewise Merge&#10;Join&lt;/a&gt;.&lt;/p&gt;&#10;&lt;h2 id="10-the-streaming-engine-is-a-pipeline-of-morsels"&gt;10. The streaming engine is a pipeline of morsels&lt;/h2&gt;&#10;&lt;p&gt;The streaming engine never materialises a whole partition. A source node&#10;emits &lt;em&gt;morsels&lt;/em&gt; — fixed-size blocks of rows — and downstream nodes consume&#10;them. The pipe between two nodes is a bounded channel, so backpressure is&#10;structural: a slow consumer stops the producer.&lt;/p&gt;&#10;&lt;div class="code-block"&gt;&#10; &lt;div class="code-block-head"&gt;&#10; &lt;span class="code-lang"&gt;rust&lt;/span&gt;&#10; &lt;button class="code-copy" type="button" data-copy&gt;Copy&lt;/button&gt;&#10; &lt;/div&gt;&#10; &lt;div class="code-block-body"&gt;&#10; &lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-rust" data-lang="rust"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// crates/polars-stream/src/morsel.rs:83&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;pub&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="nc"&gt;Morsel&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="sd"&gt;/// The data contained in this morsel.&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;sf&lt;/span&gt;: &lt;span class="nc"&gt;SpillFrame&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="sd"&gt;/// The sequence number of this morsel. May only stay equal or increase&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="sd"&gt;/// within a pipeline.&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;seq&lt;/span&gt;: &lt;span class="nc"&gt;MorselSeq&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&#10; &lt;/div&gt;&#10;&lt;/div&gt;&#10;&lt;p&gt;&lt;code&gt;crates/polars-stream/src/morsel.rs:83&lt;/code&gt;&lt;/p&gt;&#10;&lt;p&gt;When a stage has to repartition — a hash join, a group-by — the rows are&#10;&lt;em&gt;shuffled&lt;/em&gt;: hashed into N partitions, buffered, and exchanged. The hash is a&#10;multiply-shift, and the partitioning is a counting sort, not a sort.&lt;/p&gt;&#10;&lt;p&gt;Full treatment: &lt;a href="https://articles.9j.nz/posts/how-polars-splits-a-streaming-query-into-morsels/"&gt;Polars&amp;rsquo; New Streaming Engine Works in&#10;Morsels&lt;/a&gt; and&#10;&lt;a href="https://articles.9j.nz/posts/how-polars-shuffles-hash-partitions-between-streaming-stages/"&gt;Polars Hash-Shuffles Rows Between Streaming&#10;Stages&lt;/a&gt;.&lt;/p&gt;&#10;&lt;h2 id="11-the-runtime-filter-a-join-that-tells-the-scan-what-to-skip"&gt;11. The runtime filter: a join that tells the scan what to skip&lt;/h2&gt;&#10;&lt;p&gt;The newest trick in the tree is the runtime filter. When a hash join builds&#10;its table on one side, the &lt;em&gt;values&lt;/em&gt; of the build keys are known — and can be&#10;published as a predicate that the probe-side scan applies. A scan that would&#10;have read a whole partition can now skip row groups whose statistics cannot&#10;match the build key range, or check a bloom filter of the build keys before&#10;decoding anything.&lt;/p&gt;&#10;&lt;p&gt;It is a join and a scan cooperating through a slot in the plan that is filled&#10;at runtime.&lt;/p&gt;&#10;&lt;p&gt;Full treatment: &lt;a href="https://articles.9j.nz/posts/how-polars-publishes-a-joins-build-side-as-a-runtime-filter/"&gt;Polars Publishes a Join&amp;rsquo;s Build Side as a Runtime&#10;Filter&lt;/a&gt;.&lt;/p&gt;&#10;&lt;h2 id="12-python-is-a-guest-not-the-host"&gt;12. Python is a guest, not the host&lt;/h2&gt;&#10;&lt;p&gt;The Python bindings do not own the data. &lt;code&gt;pl.DataFrame&lt;/code&gt; wraps a Rust&#10;&lt;code&gt;DataFrame&lt;/code&gt;; handing it to pandas or Arrow exports it through the Arrow C&#10;data interface, which is a set of pointers plus a release callback. The GIL&#10;is dropped for the duration of a query and re-taken only where Python code&#10;actually runs — inside a UDF.&lt;/p&gt;&#10;&lt;p&gt;Full treatment: &lt;a href="https://articles.9j.nz/posts/how-polars-shares-data-with-python-over-the-arrow-c-data-interface/"&gt;Polars Shares Data With Python Over the Arrow C Data&#10;Interface&lt;/a&gt;&#10;and &lt;a href="https://articles.9j.nz/posts/how-polars-releases-the-gil-before-it-does-any-real-work/"&gt;Polars Releases the GIL Before It Does Any Real&#10;Work&lt;/a&gt;.&lt;/p&gt;&#10;&lt;h2 id="the-bottom-line"&gt;The bottom line&lt;/h2&gt;&#10;&lt;p&gt;If you want the mental model in one paragraph: Polars represents data as&#10;immutable, chunked, refcounted Arrow buffers with 16-byte inline strings;&#10;it compiles a user program into an arena-allocated IR through a stack of&#10;structural rewrite rules; and it executes that IR with one of two runtimes,&#10;one of which streams morsels through a graph of pipes with hash shuffles at&#10;the boundaries.&lt;/p&gt;&#10;&lt;p&gt;Almost every performance knob in Polars follows from those three sentences.&#10;A columnar layout is what makes the predicate-pushdown and statistics&#10;pruning possible. An arena is what makes the optimizer cheap enough to run&#10;aggressively. Morsels are what make the streaming engine&amp;rsquo;s memory usage&#10;independent of the input size.&lt;/p&gt;&#10;&lt;p&gt;The articles in this series take each of those ideas apart. If you only read&#10;one, read &lt;a href="https://articles.9j.nz/posts/how-polars-splits-a-streaming-query-into-morsels/"&gt;Polars&amp;rsquo; New Streaming Engine Works in&#10;Morsels&lt;/a&gt; — it is&#10;the newest part of the engine and the least documented.&lt;/p&gt;&#10;</content:encoded></item></channel></rss>