Skip to main content
SQLBuild projects are configured with two files in the project root:
  • sqlbuild_project.toml - shared project configuration, committed to version control
  • sqlbuild_local.toml - local developer overrides, gitignored

sqlbuild_project.toml

A complete example:
name = "waffle_shop"
adapter = "duckdb"
default_target = "dev"

[connection]
database = "waffle_shop_control.duckdb"

[settings]
default_audit_severity = "warn"

[defaults]
materialized = "table"

[targets.prod]
schema = "prod"

[targets.dev]
schema = "dev"

[path_defaults."models/staging"]
materialized = "view"

Required fields

FieldDescription
nameProject name. Used in fingerprint tracking and manifest generation.
adapterDatabase adapter: duckdb, motherduck, snowflake, bigquery, databricks, postgres, or sqlserver. See Adapters.
default_targetName of the target to build against when none is selected (see Targets).

Connection

The connection block is passed directly to the adapter. For DuckDB:
[connection]
database = "my_project.duckdb"
Targets can override the connection:
[targets.prod]
schema = "prod"

[targets.prod.connection]
database = "prod.duckdb"

[targets.dev]
schema = "dev"

[targets.dev.connection]
database = "dev.duckdb"

Targets

A target is a named build context - the schema, database, or connection you build against (for example dev and prod). Targets let you build to different places from the same project. Each target can override:
FieldDescription
schemaSchema for all models in this target
databaseDatabase for all models in this target
connectionOverride the base connection config
varsTarget-specific project variables
defer_sources_toTarget name to read managed source data from (see Loaders)
reuse_fromTarget name to reuse relations from when version identities match (see Planning: Reuse from production)
reuse_hard_copyForce a full data copy instead of zero-copy clone when reusing (default: false)
cloneClone policy (see below)
[targets.prod]
schema = "prod"

[targets.prod.vars]
source_schema = "raw_prod"

[targets.dev]
schema = "dev"

[targets.dev.vars]
source_schema = "raw_dev"

[targets.staging]
schema = "staging"

[targets.staging.connection]
database = "staging.duckdb"

Selecting a target

The active target is determined by (in order of precedence):
  1. --target on the command line (highest priority)
  2. sqlbuild_local.toml target field
  3. default_target in sqlbuild_project.toml
  4. No target (models build to the default schema)

Clone policies

Targets can declare whether they allow cloning to or from:
[targets.prod]
schema = "prod"

[targets.prod.clone]
allow_as_source = true
allow_as_target = false

[targets.dev]
schema = "dev"

[targets.dev.clone]
allow_as_source = false
allow_as_target = true

Defaults

Project-wide model defaults. Any field you can set in a MODEL() header can be set here as a default:
[defaults]
materialized = "table"
incremental_strategy = "delete_insert"
replay_on_change = "full"
tags = ["managed"]
These apply to all models unless overridden by path defaults or the model’s own MODEL() header.

Path defaults

Per-directory model defaults. Useful for applying different config to different parts of your project:
[path_defaults."models/staging"]
materialized = "view"
tags = ["staging"]

[path_defaults."models/marts"]
materialized = "table"
tags = ["marts"]
replay_on_change = "full"
Path matching uses the model’s relative file path. A model at models/staging/stg_orders.sql matches the models/staging path default.

Config layering order

Configuration is layered in this order, with later layers overriding earlier ones:
  1. Project defaults (defaults)
  2. Path defaults (path_defaults) - if the model’s path matches
  3. MODEL() header - the model’s own config
Tags are special: they are unioned across layers rather than overridden. A model with tags [marts] in its header that matches a path default with tags [managed] will have both tags.

Settings

Global feature toggles:
[settings]
sql_analysis = true
query_change_tracking = true
sql_validation = true
concurrency = 1
auto_load_sources = true
table_promotion_mode = "staged"
default_audit_severity = "warn"
default_audit_run_scope = "final"
FieldDefaultDescription
sql_analysistrueEnable SQL validation and static analysis at compile time
virtual_environmentsfalseEnable virtual environments (versioned model outputs, promotion, rollback, state management). When false, the project runs in standard mode.
query_change_trackingtrueTrack query fingerprints for change detection
sql_validationtrueValidate SQL syntax during compilation
concurrency1Maximum parallel model execution (currently serial only)
auto_load_sourcestrueAutomatically run source loaders before building dependent models during sqb build. See Loaders.
table_promotion_modeadapter defaultstaged (CTAS to staging, audit, then promote) or direct (CTAS directly to target)
default_audit_severitywarnDefault severity for audits: warn or error
default_audit_run_scopefinalDefault run scope for audits: final or delta_and_final

Table promotion mode

  • staged (default for most adapters): Materializes into a staging table, runs audits, then swaps into the target. If audits fail, the production table is untouched.
  • direct: Creates the table directly at the target location. Audits run after materialization. Simpler but no pre-promotion safety net.

Project variables

Variables are simple string substitutions available in model SQL via the @@name syntax:
[vars]
schema_prefix = "analytics"
retention_days = "90"
Target-specific variables override project-level ones:
[vars]
schema_prefix = "analytics"

[targets.prod.vars]
schema_prefix = "prod_analytics"
See Macros for details on variable substitution and how variables interact with macros.

Janitor

Configuration for the sqb janitor command, which cleans up stale warehouse relations:
[janitor]
enabled = false
retention_days = 30
delete_tracked_only = true
exclude_patterns = ["audit_*", "tmp_*"]
FieldDefaultDescription
enabledfalseWhether janitor is active
retention_days30Only clean relations older than this many days
delete_tracked_onlytrueOnly clean relations that appear in fingerprint tracking
exclude_patterns[]Glob patterns for relations to skip

Scenario

Configuration for scenario snapshot capture safety limits and local type overrides:
[scenario.snapshot_limits]
max_rows_per_relation = 10000
max_total_rows = 50000
max_bytes_per_relation = 10485760
max_total_bytes = 52428800
FieldDefaultDescription
max_rows_per_relationnoneMaximum rows per captured relation
max_total_rowsnoneMaximum total rows across all relations in one scenario
max_bytes_per_relationnoneMaximum JSONL bytes per relation file
max_total_bytesnoneMaximum total JSONL bytes per scenario
Local type overrides for DuckDB replay are configured per adapter dialect:
[scenario.local_type_overrides.snowflake]
"OBJECT" = "JSON"
"ARRAY" = "JSON"
See Scenarios for details on local type overrides and capture limits.

dbt

Configuration for running SQLBuild alongside an existing dbt project:
[dbt]
project_dir = "../dbt_project"
profiles_dir = "../profiles"
target_path = "../dbt_project/target"
target = "dev"
replay_on_change = "full"

[dbt.reuse_from]
git_ref = "main"
generate_schema_name_override = "dbt/macros/generate_schema_name.sql"
FieldDescription
project_dirPath to the dbt project root (where dbt_project.yml lives)
profiles_dirPath to the directory containing profiles.yml
target_pathPath to dbt’s target/ directory (where manifest.json is written)
targetdbt target name override (optional)
replay_on_changeProject-wide policy for rerunning changed dbt models: forward_only (default) or full (optional). See Change-aware builds.
reuse_from.git_refProduction-shaped git branch or tag whose built tables are reused (optional). See Reuse from production.
reuse_from.generate_schema_name_overrideRelative path under dbt/macros/ to the generate_schema_name macro used when compiling the reuse ref.
Paths can be absolute or relative to the SQLBuild project root. See Using SQLBuild with dbt for setup and usage details.

Skills

Configuration for AI agent skill file installation:
[skills]
targets = ["opencode", "claude"]
FieldDefaultDescription
targetsall targetsWhich agent targets to install skill files for: opencode, claude, agents
See skills CLI reference for usage details.

sqlbuild_local.toml

Local developer overrides. This file should be gitignored.
target = "dev"

[connection]
database = "my_local.duckdb"

[settings]
sql_validation = false
concurrency = 4

[vars]
debug_mode = "true"
FieldDescription
targetOverride which target is active for this developer
adapterOverride the database adapter (e.g. use DuckDB locally while prod uses Snowflake)
connectionOverride connection config (merged on top of project + target connection)
settingsOverride global settings (only explicitly set fields take effect)
varsDeveloper-specific variable overrides (merged on top of project + target vars)
This replaces the common dbt pattern of switching profiles or setting environment variables to change targets. Each developer sets their target, connection, and preferences once in sqlbuild_local.toml and it persists across sessions.