Getting started

A short path from zero to a first model. You do not need PyPI/CRAN DuckDB for this, and duckboost is not on the community extension store yet. Until the community descriptor PR merges, the supported way to try duckboost is to clone this repository and build the bundled DuckDB 2.0 alpha shell (v2.0.0-alpha46057).

NoteWhy clone?

pip install duckdb / CRAN DuckDB are still 1.x and cannot load this extension. Community INSTALL duckboost FROM community lands after the descriptor PR merges into duckdb/community-extensions. Cloning gives you a matching 2.0 alpha CLI with duckboost already linked.

1. Prerequisites

You need a normal C++ build environment:

  • git
  • A C++17 compiler (clang or gcc)
  • cmake and make (optional: ninja)

On macOS, Xcode Command Line Tools plus Homebrew cmake is enough. On Ubuntu/Debian, build-essential and cmake cover it.

2. Clone and build

git clone --recurse-submodules https://github.com/JavOrraca/duckboost.git
cd duckboost
make

If you already cloned without submodules:

git submodule update --init --recursive
make

make produces:

  • ./build/release/duckdb — CLI with duckboost statically linked
  • ./build/release/extension/duckboost/duckboost.duckdb_extension — loadable extension file

Optional: GEN=ninja make if Ninja is installed. make test runs the SQL tests under test/sql/ (not required just to try the examples).

3. Open the shell

./build/release/duckdb -unsigned

In that shell, duckboost is already registered, so this works:

LOAD duckboost;
SELECT backend, training_supported, notes
FROM duckboost_backends()
ORDER BY backend;
LOAD duckboost;
SELECT backend, training_supported, notes
FROM duckboost_backends()
ORDER BY backend;
┌───────────┬────────────────────┬──────────────────────────────────────────────────────────────────────────────────────────────────────┐
│  backend  │ training_supported │                                                notes                                                 │
├───────────┼────────────────────┼──────────────────────────────────────────────────────────────────────────────────────────────────────┤
│ catboost  │ false              │ import save_model JSON via duckboost_import; native train requires dump import (no public C API)     │
│ lightgbm  │ false              │ import save_model text via duckboost_import; native train requires DUCKBOOST_WITH_LIGHTGBM           │
│ reference │ true               │ in-process native histogram GBDT (backend aliases: native, reference; train/predict/evaluate/to_sql) │
│ xgboost   │ false              │ import dump_model JSON via duckboost_import; native train requires DUCKBOOST_WITH_XGBOOST            │
└───────────┴────────────────────┴──────────────────────────────────────────────────────────────────────────────────────────────────────┘

training_supported is true only for backends this binary can train in-process. A default make enables the native histogram trainer (pass backend = 'native' in train options; model JSON may still say "reference"). XGBoost, LightGBM, and CatBoost stay import-only unless you linked the vendor libraries — see the README build notes.

To load the .duckdb_extension into a different DuckDB 2.0 shell (not this repo’s binary), build that shell from the same duckdb submodule commit:

/path/to/other/duckdb -unsigned
LOAD '/path/to/duckboost/build/release/extension/duckboost/duckboost.duckdb_extension';

4. First model

Train a small body-mass regression on the Palmer penguins data. Named features, an explicit target, and training RMSE show the usual loop: table → feature list → duckboost_train → metric.

From a checkout, the most reliable load is the thin CSV under data/ (no network). On released DuckDB with httpfs, the same file is also on GitHub raw HTTPS — the SQL below uses that public URL so you can copy it into any networked session. Swap in read_csv('data/penguins.csv', nullstr = 'NA') if you are offline in this repo’s shell.

Each block on this site starts a new in-memory database.

LOAD duckboost;

CREATE TABLE penguins AS
SELECT
  body_mass_g::DOUBLE AS body_mass_g,
  [bill_length_mm, bill_depth_mm, flipper_length_mm, (sex = 'male')::DOUBLE] AS features
FROM read_csv('https://raw.githubusercontent.com/allisonhorst/palmerpenguins/master/inst/extdata/penguins.csv', nullstr = 'NA')
WHERE body_mass_g IS NOT NULL
  AND bill_length_mm IS NOT NULL
  AND sex IS NOT NULL;

CREATE TABLE models AS
SELECT duckboost_train(
  body_mass_g, features,
  MAP {
    'backend': 'native',
    'n_estimators': '40',
    'max_depth': '3',
    'learning_rate': '0.15',
    'feature_names': 'bill_length_mm,bill_depth_mm,flipper_length_mm,male'
  }
) AS model
FROM penguins;

SELECT round(duckboost_evaluate_agg(
  model, body_mass_g, features, MAP {'metric': 'rmse'}
), 1) AS rmse_g
FROM models, penguins;
┌────────┐
│ rmse_g │
├────────┤
│ 224.4  │
└────────┘

A few predictions next to the measured mass:

LOAD duckboost;

CREATE TABLE penguins AS
SELECT
  body_mass_g::DOUBLE AS body_mass_g,
  [bill_length_mm, bill_depth_mm, flipper_length_mm, (sex = 'male')::DOUBLE] AS features
FROM read_csv('https://raw.githubusercontent.com/allisonhorst/palmerpenguins/master/inst/extdata/penguins.csv', nullstr = 'NA')
WHERE body_mass_g IS NOT NULL
  AND bill_length_mm IS NOT NULL
  AND sex IS NOT NULL;

CREATE TABLE models AS
SELECT duckboost_train(
  body_mass_g, features,
  MAP {
    'backend': 'native',
    'n_estimators': '40',
    'max_depth': '3',
    'learning_rate': '0.15',
    'feature_names': 'bill_length_mm,bill_depth_mm,flipper_length_mm,male'
  }
) AS model
FROM penguins;

SELECT
  round(body_mass_g, 0) AS body_mass_g,
  round(duckboost_predict(model, features), 0) AS pred_g
FROM models, penguins
ORDER BY body_mass_g
LIMIT 5;
┌─────────────┬────────┐
│ body_mass_g │ pred_g │
├─────────────┼────────┤
│ 2700.0      │ 3140.0 │
│ 2850.0      │ 2955.0 │
│ 2850.0      │ 3195.0 │
│ 2900.0      │ 3026.0 │
│ 2900.0      │ 3272.0 │
└─────────────┴────────┘

After community publication

Once duckboost is on the community extension store, analysts can skip the clone/build steps:

INSTALL duckboost FROM community;
LOAD duckboost;

That path is not live yet. The descriptor is ready in docs/community_extensions_description.yml; see docs/COMMUNITY_PUBLISH.md for the submission checklist. Until the community PR merges, stay on the clone path above.

Next steps