Getting Started¶
Build from Source¶
Vizier requires Zig 0.15.2 and a DuckDB binary (version 1.2.0 or newer) for testing.
git clone --depth=1 https://github.com/CogitatorTech/vizier.git
cd vizier
# Build the extension
make build-all
# Run tests (optional; needs DuckDB in PATH)
make test
# Try Vizier interactively (needs DuckDB in PATH)
make duckdb
Install from DuckDB¶
The hosted repository currently includes binaries for DuckDB v1.2.0 to v1.5.0.
Vizier is currently distributed as an unsigned extension. Start DuckDB with
-unsigned, or enable unsigned extensions in your client before installing and loading Vizier.
Download from the Release Page¶
Open the latest release for release notes and platform-specific zip downloads:
- Linux AMD64:
vizier-linux-amd64.zip - Linux ARM64:
vizier-linux-arm64.zip - Linux AMD64 (musl):
vizier-linux-amd64-musl.zip - Linux ARM64 (musl):
vizier-linux-arm64-musl.zip - macOS ARM64:
vizier-macos-arm64.zip - Windows AMD64:
vizier-windows-amd64.zip - Windows ARM64:
vizier-windows-arm64.zip - FreeBSD AMD64:
vizier-freebsd-amd64.zip
Loading the Extension¶
After installing Vizier from the hosted extension repository:
Basic Workflow¶
Vizier follows a capture, analyze, and apply workflow.
1. Capture Queries¶
Feed Vizier the queries you run against your database:
select * from vizier_capture('select * from events where account_id = 42 and ts >= date ''2026-01-01''');
select * from vizier_capture('select count(*) from orders group by customer_id');
select * from vizier_capture('select * from events where account_id = 42 and ts >= date ''2026-01-01''');
Flush captured queries to metadata tables:
2. Review the Workload¶
┌──────────────┬──────────────────────────────────────────────────────────────────────────┬───────┬─────────────────────┬────────┐
│ sig │ sql │ runs │ last_seen │ avg_ms │
├──────────────┼──────────────────────────────────────────────────────────────────────────┼───────┼─────────────────────┼────────┤
│ 8c9d7175aab0 │ SELECT * FROM events WHERE account_id = 42 AND ts >= DATE '2026-01-01' │ 2 │ 2026-03-22 16:44:06 │ 0.0 │
│ 2af899d9dba6 │ SELECT count(*) FROM orders GROUP BY customer_id │ 1 │ 2026-03-22 16:44:06 │ 0.0 │
└──────────────┴──────────────────────────────────────────────────────────────────────────┴───────┴─────────────────────┴────────┘
3. Analyze and Get Recommendations¶
Each recommendation includes a kind, target table, SQL to execute, score, and confidence level.
4. Apply a Recommendation¶
Preview first with a dry run:
Then apply:
5. Measure the Impact¶
select * from vizier_benchmark('select * from events where account_id = 42', 10);
select * from vizier_compare(1);
Persistent State¶
By default, Vizier state is in-memory. To persist across sessions:
-- Initialize with a state file
select * from vizier_init('/path/to/vizier_state.db');
-- Or configure the path (auto-loads on next extension init)
select vizier_configure('state_path', '/path/to/vizier_state.db');
You can also export and import state between environments:
select * from vizier_save('/tmp/vizier_state.db');
select * from vizier_load('/tmp/vizier_state.db');
Bulk Capture¶
If you have a table with query logs:
Session Capture¶
Capture all queries in a session without calling vizier_capture() per query:
Import from Profiling Output¶
If you have a DuckDB JSON profiling file:
Import from dbt¶
If you use dbt with DuckDB, you can import your dbt run results into Vizier.
The import_dbt.py script reads compiled SQL from manifest.json and execution timing from run_results.json:
# Import all successful model runs
python scripts/import_dbt.py --db my_database.duckdb
# Only import models that took longer than 0.5 seconds
python scripts/import_dbt.py --db my_database.duckdb --min-time 0.5
# Preview what would be imported without executing
python scripts/import_dbt.py --db my_database.duckdb --dry-run
By default, the script reads from the target/ directory.
Use --target to point to a different location.