Build1 distinct publisher3 min readUpdated
A rebuild that deleted Ibis and made a parsed query tree canonical shows how the layer nobody markets decides whether laziness, portability and change detection are even possible.
The Engineer · Build desk

Compiled by The EngineerSomething wrong?How this is made
A rebuild that deleted Ibis and made a parsed query tree canonical shows how the layer nobody markets decides whether laziness, portability and change detection are even possible.
Interlace's 2.0 rebuild committed to one sentence about its internals: the canonical intermediate representation is a sqlglot AST plus an Arrow schema, the canonical wire format is an Arrow `RecordBatchReader`, and materialisation happens exactly once, at the sink, as a single native SQL statement executed inside the owning engine [5]. According to the project's own writeup, every data tool has an IR whether it admits to one or not, and that layer quietly decides the ceiling on what the tool can do [1].
The evidence offered is a failure, not a benchmark. An earlier iteration of Interlace effectively used a pandas DataFrame as its IR: every model boundary ran an eager `.execute()` and fed the result back in [3]. That single choice cost laziness, dialect portability and any prospect of semantic change detection at once [4] - three symptoms with one cause [6]. The comparison the author draws is dbt, whose IR is templated text, which is why `ref()` is a string and why a macro can emit SQL no analyser can reason about [2].
The clean-up was expensive. Dropping Ibis was the single largest deletion in the rebuild [7]. The stated reason is not quality but redundancy: Ibis was acting as a data plane moving results between models while itself sitting on Arrow, and as an expression builder that compiles to sqlglot - both of which the project had already chosen directly [8]. Removing it dropped a heavyweight dependency and its governance risk for zero lost capability, with remote engines now connecting over ADBC instead of Ibis backends, a narrower and better-specified contract [9][10].
What the parsed tree buys is concrete [11]. Strategies become AST builders rather than string templates: each takes a model's query expression and its target and emits a short list of SQL statements applied in one transaction, with dialect appearing only at `transpile()` [12]. In 0.x each strategy hand-wrote DuckDB SQL [13]. Because no strategy needs the model's column list, a schema change needs no hand-written migration; a definition change mints a new snapshot table [14]. Dependencies are parsed rather than declared: `FROM` and `JOIN` are structure, a reference matching a model name becomes a DAG edge, and CTEs are excluded because the parser knows what a CTE is [15]. There is no `ref()` to write - `raw_orders` is a real table reference rewritten to the right snapshot at build time [16].
The payoff the author says justifies the whole decision is diffing trees instead of strings: `interlace plan` can distinguish a change that alters output from one that does not, then narrow per column to the downstream models genuinely affected [17]. The analyser is deliberately conservative. Adding `avg(amount) AS avg_amount` is additive; anything touching existing expressions, plus `SELECT *` rewrites, `DISTINCT` and positional `GROUP BY`, is treated as breaking, and ambiguity errs toward rebuilding rather than a false skip [18]. On the data side, Python models receive and return Arrow, and because it is a reader rather than a table they can stream with bounded memory regardless of upstream size [19] - the property the old `.execute()` to pandas to `memtable()` round-trip destroyed at every hop [20]. pandas and Polars survive as optional extras at the edges, not as the interchange format [21].
This is a single project's account of its own architecture, with no benchmarks, adoption figures or outside evaluation [22]. Watch three things: whether the conservative classifier generates enough false-breaking rebuilds to erode the value of per-column analysis [18], whether ADBC really covers the engine surface Ibis backends did [9], and whether transpile-at-the-end holds up once a second and third dialect are in production [12].
Follow any of these and your For You feed starts watching them — no settings page required.
Ranked by verification strength, evidence, and original report placement.
Every data tool has an intermediate representation whether it admits to one or not; it is what a model becomes after parsing and before execution, and it quietly decides what the tool can do.
dbt's IR is templated text, which is why ref() is a string and why a macro can produce SQL no analyser can reason about.
The author frames the three lost properties as 'three properties, one root cause' and states that setting the ceiling is what an IR does.
A sqlglot AST is a parsed, structured, dialect-neutral representation of the query, with three consequences that matter.
Dependencies are parsed rather than declared: FROM and JOIN clauses are structure rather than text, a reference whose name or last dotted segment matches another model becomes a DAG edge, and CTEs are excluded because the parser knows what a CTE is.
There is no ref() to write; in the example, raw_orders is a real table reference that happens to resolve to a model and is rewritten to the right snapshot at build time.
Evidence-backed comparisons of source perspectives and observed adoption signals. Read the methodology
Which Builder, Operator, and Investor concerns the observed source mix emphasized—not a truth score.
Evidence, demonstrated adoption, hype gap, incentives, and confidence are assessed independently, each on its own current evidence. How these are measured.
Detailed self-reported design, no external verification
The architecture is documented in unusual specificity — a stated one-sentence IR commitment, code for strategies, dependency parsing via table_references(parse(sql)), a @model streaming example, an enumerated dependency list, and a fingerprint table showing identical hashes for reformatted SQL and a differing hash for sum→avg. That is real, checkable-in-principle detail, which lifts this above pure assertion. But every source is the project author's own dev.to post: there are no benchmarks, no measured memory or runtime figures, no engine coverage matrix behind 'zero lost capability', and no independent evaluation, so the strongest capability claims rest on maintainer narrative.
No adoption evidence in supplied sources
The only adoption-adjacent facts available are the project's own release disclosures — the 2.0 rebuild and the later addition of AST-expanded macros. Nothing in the supplied material reports users, deployments, downloads, contributors, production runs or any external usage of Interlace at any version, so no adoption level can be measured without inventing facts.
Mildly overstated: absolute claims outrun the measurement
The writing is comparatively candid for maintainer material — it names the author's own prior design as the failure case, states the change analyser is deliberately conservative, and frames the Ibis deletion as 'not Ibis is bad' — which keeps the gap small. The overhang comes from absolute phrasing on unmeasured properties: 'zero lost capability' after removing a multi-backend library, memory 'bounded no matter how large the upstream is', and identifying which downstream models are 'genuinely affected', none supported by benchmarks, coverage matrices or any user running the system. Claims are therefore somewhat ahead of the evidence, and well ahead of any demonstrated adoption.
Maintainer-authored advocacy for its own architecture
Both cluster items are self-published by the project's own author on dev.to, argue for choices that author made, position the project against dbt and Ibis, and route readers onward to the project's docs and the next post in the series. The incentive to present the rebuild as strictly superior is direct and undisclosed as such. Mitigating factors: no pricing, funding or commercial ask appears, prior self-designs are criticised by name, and one post publicly revises its own earlier claim via an August 2026 macros update — so this reads as promotional engineering writing rather than sales material.
Single-publisher, single-author basis
The design facts are clearly and consistently stated across two sources, so what the project claims to be is well established. Confidence in the claims' truth and significance is limited by structure rather than clarity: one publisher, one project author, no independent verification, no adoption signal, and truncated closing sections in both supplied texts. The transferable design argument can be judged on its own logic; the specific performance and capability assertions cannot be confirmed from this material.
build
Once the question needs a cube, you own the parser1 distinct publisher
build
DuckDB is growing a server, and someone on your team will have to run it1 distinct publisher
build
Before you spend quota on an agent skill, make it pass an eval harness1 distinct publisher
build
Four YAML parsers, two specs: the failure mode is both of them being right1 distinct publisher
Distinct publishers with included, body-backed reporting in this cluster.
dev.to
2 articles · August 15, 2026