> ## Documentation Index
> Fetch the complete documentation index at: https://docs.sqlbuild.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Project Configuration

> Configure your SQLBuild project with sqlbuild_project.toml and sqlbuild_local.toml.

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:

```toml theme={null}
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

| Field            | Description                                                                                                                                      |
| ---------------- | ------------------------------------------------------------------------------------------------------------------------------------------------ |
| `name`           | Project name. Used in fingerprint tracking and manifest generation.                                                                              |
| `adapter`        | Database adapter: `duckdb`, `motherduck`, `snowflake`, `bigquery`, `databricks`, `postgres`, or `sqlserver`. See [Adapters](/concepts/adapters). |
| `default_target` | Name of the target to build against when none is selected (see [Targets](#targets)).                                                             |

### Connection

The `connection` block is passed directly to the adapter. For DuckDB:

```toml theme={null}
[connection]
database = "my_project.duckdb"
```

Targets can override the connection:

```toml theme={null}
[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:

| Field              | Description                                                                                                                      |
| ------------------ | -------------------------------------------------------------------------------------------------------------------------------- |
| `schema`           | Schema for all models in this target                                                                                             |
| `database`         | Database for all models in this target                                                                                           |
| `connection`       | Override the base connection config                                                                                              |
| `vars`             | Target-specific project variables                                                                                                |
| `defer_sources_to` | Target name to read managed source data from (see [Loaders](/concepts/python-nodes/loaders#source-deferral))                     |
| `reuse_from`       | Target name to reuse relations from when version identities match (see [Reuse from production](/concepts/reuse-from-production)) |
| `reuse_hard_copy`  | Force a full data copy instead of zero-copy clone when reusing (default: `false`)                                                |
| `clone`            | Clone policy (see below)                                                                                                         |

```toml theme={null}
[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:

```toml theme={null}
[targets.prod]
schema = "prod"

[targets.prod.clone]
allow_as_clone_origin = true
allow_as_clone_destination = false

[targets.dev]
schema = "dev"

[targets.dev.clone]
allow_as_clone_origin = false
allow_as_clone_destination = true
```

Both policies default to `false`. `sqb clone --from prod --to dev` requires `allow_as_clone_origin = true` on `prod` and `allow_as_clone_destination = true` on `dev`.

## Defaults

Project-wide model defaults. Any field you can set in a `MODEL()` header can be set here as a default:

```toml theme={null}
[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:

```toml theme={null}
[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

Most keys are overridden by the more specific layer, but three merge instead:

* `tags` are *unioned* across layers. A model with `tags [marts]` in its header that matches a path default with `tags [managed]` will have both tags.
* `row_diff_exclude_columns` lists are unioned across layers.
* `row_diff_tolerances` mappings are deep-merged across layers, so a header tolerance for one column adds to (rather than replaces) tolerances declared in defaults or path defaults.

## Settings

Global feature toggles:

```toml theme={null}
[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"
```

| Field                     | Default         | Description                                                                                                                                                                                                                                                                                                               |
| ------------------------- | --------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `sql_analysis`            | `true`          | Enable SQL validation and static analysis at compile time                                                                                                                                                                                                                                                                 |
| `changes_only`            | `false`         | Enable [change-aware pruning](/concepts/planning#changes-only-mode) for `plan`, `build`, and `sqb dbt` execution without passing `--changes-only` each run. Can also be set per target under `[targets.<name>]`. The CLI flag takes precedence, then the selected target, then local settings, then this project setting. |
| `virtual_environments`    | `false`         | Enable [virtual environments](/concepts/virtual-environments) (versioned model outputs, promotion, rollback, state management). When `false`, the project runs in standard mode.                                                                                                                                          |
| `query_change_tracking`   | `true`          | Track query fingerprints for change detection                                                                                                                                                                                                                                                                             |
| `sql_validation`          | `true`          | Validate SQL syntax during compilation                                                                                                                                                                                                                                                                                    |
| `concurrency`             | `1`             | Maximum parallel model execution (currently serial only)                                                                                                                                                                                                                                                                  |
| `auto_load_sources`       | `true`          | Automatically run source loaders before building dependent models during `sqb build`. See [Loaders](/concepts/python-nodes/loaders).                                                                                                                                                                                      |
| `table_promotion_mode`    | adapter default | `staged` (CTAS to staging, audit, then promote) or `direct` (CTAS directly to target)                                                                                                                                                                                                                                     |
| `default_audit_severity`  | `warn`          | Default severity for audits: `warn` or `error`                                                                                                                                                                                                                                                                            |
| `default_audit_run_scope` | `final`         | Default 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:

```toml theme={null}
[vars]
schema_prefix = "analytics"
retention_days = "90"
```

Target-specific variables override project-level ones:

```toml theme={null}
[vars]
schema_prefix = "analytics"

[targets.prod.vars]
schema_prefix = "prod_analytics"
```

See [Macros](/concepts/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:

```toml theme={null}
[janitor]
enabled = false
retention_days = 30
delete_tracked_only = true
exclude_patterns = ["audit_*", "tmp_*"]
```

| Field                 | Default | Description                                              |
| --------------------- | ------- | -------------------------------------------------------- |
| `enabled`             | `false` | Whether janitor is active                                |
| `retention_days`      | `30`    | Only clean relations older than this many days           |
| `delete_tracked_only` | `true`  | Only 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:

```toml theme={null}
[scenario.snapshot_limits]
max_rows_per_relation = 10000
max_total_rows = 50000
max_bytes_per_relation = 10485760
max_total_bytes = 52428800
```

| Field                    | Default | Description                                             |
| ------------------------ | ------- | ------------------------------------------------------- |
| `max_rows_per_relation`  | none    | Maximum rows per captured relation                      |
| `max_total_rows`         | none    | Maximum total rows across all relations in one scenario |
| `max_bytes_per_relation` | none    | Maximum JSONL bytes per relation file                   |
| `max_total_bytes`        | none    | Maximum total JSONL bytes per scenario                  |

Local type overrides for DuckDB replay are configured per adapter dialect:

```toml theme={null}
[scenario.local_type_overrides.snowflake]
"OBJECT" = "JSON"
"ARRAY" = "JSON"
```

See [Scenarios](/concepts/scenarios) for details on local type overrides and capture limits.

## dbt

Configuration for running SQLBuild alongside an existing dbt project:

```toml theme={null}
[dbt]
project_dir = "../dbt_project"
profiles_dir = "../profiles"
target_path = "../dbt_project/target"
target = "dev"
replay_on_change = "full"

[dbt.production_ref]
git_ref = "main"
generate_schema_name_override = "dbt/macros/generate_schema_name.sql"
```

| Field                                          | Description                                                                                                                                                                                                             |
| ---------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `project_dir`                                  | Path to the dbt project root (where `dbt_project.yml` lives)                                                                                                                                                            |
| `profiles_dir`                                 | Path to the directory containing `profiles.yml`                                                                                                                                                                         |
| `target_path`                                  | Path to dbt's `target/` directory (where `manifest.json` is written)                                                                                                                                                    |
| `target`                                       | dbt target name override (optional)                                                                                                                                                                                     |
| `replay_on_change`                             | Project-wide policy for rerunning changed dbt models: `forward_only` (default) or `full` (optional). See [Change-aware builds](/concepts/dbt-compatibility/change-aware-builds#replay-on-change).                       |
| `production_ref.git_ref`                       | Production-shaped git branch or tag compiled to locate production relations, used by `sqb dbt clone` and `sqb dbt diff` (optional). See [Configuration](/concepts/dbt-compatibility/overview#the-production-ref-block). |
| `production_ref.generate_schema_name_override` | Relative path under `dbt/macros/` to the `generate_schema_name` macro injected when compiling the production ref.                                                                                                       |

Paths can be absolute or relative to the SQLBuild project root. See [Using SQLBuild with dbt](/concepts/dbt-compatibility/overview) for setup and usage details.

## Skills

Configuration for AI agent skill file installation:

```toml theme={null}
[skills]
targets = ["opencode", "claude"]
```

| Field     | Default     | Description                                                                    |
| --------- | ----------- | ------------------------------------------------------------------------------ |
| `targets` | all targets | Which agent targets to install skill files for: `opencode`, `claude`, `agents` |

See [skills CLI reference](/cli/skills) for usage details.

## sqlbuild\_local.toml

Local developer overrides. This file should be gitignored.

```toml theme={null}
target = "dev"

[connection]
database = "my_local.duckdb"

[settings]
sql_validation = false
concurrency = 4

[vars]
debug_mode = "true"
```

| Field        | Description                                                                       |
| ------------ | --------------------------------------------------------------------------------- |
| `target`     | Override which target is active for this developer                                |
| `adapter`    | Override the database adapter (e.g. use DuckDB locally while prod uses Snowflake) |
| `connection` | Override connection config (merged on top of project + target connection)         |
| `settings`   | Override global settings (only explicitly set fields take effect)                 |
| `vars`       | Developer-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.
