virtual_environments = true in your project settings, and a state store configured for your active target.
Project configuration
virtual_environments setting switches the project from standard mode (default) to virtual mode. All state, plan, build, promote, rollback, and reconcile commands route through the virtual path when this is enabled.
State configuration
Each physical target that uses virtual mode needs a[targets.<name>.state] block:
| Field | Required | Description |
|---|---|---|
backend | Yes | State store engine: duckdb or postgres |
schema | Yes | Schema name for state tables |
connection | Yes | Backend-specific connection config |
allow_reset | No | Whether sqb state reset is permitted (default: false) |
unsuffixed_virtual_env | No | VDE name that uses the base schema without a suffix (for adopt/detach) |
DuckDB state backend
Postgres state backend
State initialization
Before using virtual commands, initialize the state store:State lifecycle
| Command | Description |
|---|---|
sqb state init | Create state tables |
sqb state migrate | Back up current state and re-initialize tables |
sqb state rollback | Restore from the latest backup |
sqb state rollback --backup-id <id> | Restore from a specific backup |
sqb state reset --auto-approve | Drop all state tables (requires allow_reset = true) |
state migrate creates a backup schema (e.g. sqlbuild_state__backup_<id>) before re-initializing. This lets you roll back if a migration causes problems.
state reset is destructive and requires both allow_reset = true in config and --auto-approve on the command line.
Local overrides
Usesqlbuild_local.toml to override state connection config per developer:
Per-target state
Different physical targets can use different state backends:Unsuffixed VDE naming
By default, all VDE logical views use a suffixed schema:dev__kevin.fact_orders. For the primary VDE that consumers query directly (e.g. the production VDE), you typically want clean unsuffixed names: dev.fact_orders.
Configure this with unsuffixed_virtual_env:
dev uses dev.fact_orders while other VDEs like kevin use dev__kevin.fact_orders.
This setting is also required for adopt and detach operations so that existing consumer queries continue to work after migrating to virtual mode.
Janitor configuration
When using virtual environments, configure the janitor to run periodically to clean up expired VDEs, old checkpoints, and unreferenced physical versions:State tables
The state store contains current-state tables and append-only history tables. You do not need to interact with these directly, but understanding what is stored helps when debugging: Current state:state_versions, model_versions, function_versions, physical_relations, physical_relation_ancestry, virtual_environments, virtual_environment_refs, virtual_environment_function_refs, virtual_environment_checkpoints, virtual_environment_checkpoint_refs, virtual_environment_checkpoint_function_refs, locks, state_operations
History: plan_runs, virtual_environment_ref_events, reconcile_events, state_migration_events, state_operation_events
