Quickstart

From zero to incremental in a few lines.

OpenIVM is under active testing and currently needs a source build against DuckDB v1.5.4. A DuckDB community extension is planned for the end of 2026.

1

Build

You need git, CMake ≥ 3.5, a C++ compiler, and optionally Ninja for faster builds.

git clone --recurse-submodules https://github.com/ila/openivm.git
cd openivm
GEN=ninja make            # release build; plain `make` works without ninja

# The built DuckDB CLI already loads OpenIVM
./build/release/duckdb my.db
2

Create a view and refresh it

Create a view, change the base table, refresh. Only the new rows are processed.

CREATE TABLE sales (region VARCHAR, product VARCHAR, amount INT);
INSERT INTO sales VALUES ('US', 'Widget', 100), ('EU', 'Gadget', 200);

CREATE MATERIALIZED VIEW regional_totals AS
    SELECT region, SUM(amount) AS total, COUNT(*) AS cnt
    FROM sales GROUP BY region;

-- Changes are captured as deltas automatically
INSERT INTO sales VALUES ('US', 'Bolt', 50), ('JP', 'Gear', 300);
DELETE FROM sales WHERE product = 'Gadget';

PRAGMA refresh('regional_totals');

SELECT * FROM regional_totals ORDER BY region;
-- JP  | 300 | 1
-- US  | 150 | 2        (EU is gone: its only row was deleted)
3

Reference

PragmaWhat it does
PRAGMA refresh('v')Refresh a materialized view
PRAGMA refresh_status('v')Refresh interval, last / next refresh, status
PRAGMA refresh_cost('v')Incremental vs full recompute cost estimate
PRAGMA refresh_history('v')Past refreshes (feeds the learned cost model)
SettingDefaultDescription
openivm_refresh_modeincremental'incremental', 'full' or 'auto'
openivm_cascade_refreshdownstreamPipeline cascade: 'off', 'upstream', 'downstream', 'both'
openivm_adaptive_refreshfalsePick incremental vs full per refresh with a cost model
openivm_disable_daemonfalseTurn off background REFRESH EVERY maintenance
openivm_files_path—Directory for compiled SQL files
openivm_input_dialectduckdbDialect of view bodies, e.g. 'spark'