Configuration Reference

Complete reference for interlace.yaml, located at the project root. Every field has a default — a project works with no config file at all. All paths resolve relative to the project root.

Full Example

name: my-project
default_dialect: duckdb
default_engine: default

# The warehouse (the synthesised "default" engine)
database: 'ducklake:postgres:${WAREHOUSE_DSN}'
data_path: s3://my-bucket/warehouse/
metadata_schema: my_project_meta

secrets:
  lake:
    type: s3
    key_id: ${AWS_ACCESS_KEY_ID}
    secret: ${AWS_SECRET_ACCESS_KEY}
    region: eu-west-2

engines:
  pg:
    type: postgres
    database: 'postgresql://[email protected]:5432/analytics'

attach:
  crm: crm.duckdb
  erp: 'postgres:host=db.internal dbname=erp'

model_paths: [models]
macro_paths: [macros]
parallelism: 4
state_path: .interlace/state.db
stream_path: .interlace/streams.db

Top-Level Fields

FieldTypeDefaultDescription
namestr"interlace"Project name (also the default warehouse catalog alias)
databasestr".interlace/warehouse.duckdb"Warehouse URI — see engine URIs
default_dialectstr"duckdb"SQL dialect models are written in
enginesmapping{}Named engines — see engine fields
default_enginestr"default"Engine unpinned models run on
aliasstrproject nameWarehouse catalog’s ATTACH alias
data_pathstr—DuckLake data location (local dir or s3://...)
metadata_schemastr—Catalog schema holding this warehouse’s DuckLake metadata
secretsmapping{}Secrets created on the engine at open — see secrets
attachmapping{}Databases to ATTACH: alias: uri
quack_tokenstr—Token for quack: databases (or INTERLACE_QUACK_TOKEN)
model_pathslist[str]["models"]Where models are discovered
macro_pathslist[str]["macros"]Where CREATE MACRO definitions are discovered
parallelismint (min 1)4Models building concurrently (--parallelism overrides)
state_pathstr".interlace/state.db"Control-plane SQLite database
stream_pathstr".interlace/streams.db"Durable stream log (SQLite WAL)
event_log_pathstr—Optional NDJSON mirror of the operator event log
connectionsmapping{}Named http and postgres sources that are not warehouse engines
inputsmapping{}DuckDB file scans (parquet, csv, json, delta, iceberg)
cdcmapping{}Postgres logical slots copied into a @stream

Engine URIs

The database string determines the engine type:

FormMeaning
.interlace/warehouse.duckdbPlain DuckDB file (the default)
ducklake:.interlace/warehouse.ducklakeDuckLake, local catalog file
ducklake:postgres:dbname=lake host=db.internalDuckLake, catalog hosted in Postgres
warehouse.duckdbPlain DuckDB file (another path)
:memory:In-memory DuckDB
quack:localhost:4213Warehouse served by interlace serve --quack

Postgres as an execution engine is declared under engines: with type: postgres (never via the top-level database), and requires the adbc extra:

engines:
  pg:
    type: postgres
    database: 'postgresql://user@host:5432/dbname'

Every Postgres DSN — engine, DuckLake catalog, or attach: — must name a host explicitly (host=, a URI host, service=, or PGHOST/PGSERVICE).

Engine Fields

Each entry under engines: accepts:

FieldTypeDefaultDescription
typestr"duckdb"duckdb, ducklake, quack, or postgres
databasestr—Path/URI (falls back to .interlace/warehouse.duckdb)
dialectstrfrom typeSQL dialect (duckdb-family → duckdb, postgres → postgres)
aliasstrengine nameCatalog ATTACH alias
data_pathstr—DuckLake data location
metadata_schemastr—DuckLake metadata schema
secretsmapping{}Per-engine secrets
attachmapping{}Per-engine ATTACHes
quack_tokenstr—Token when database is quack:

An engine named default overrides the synthesised warehouse engine entirely.

Secret Fields

Each entry under secrets: becomes a CREATE SECRET on the engine at open — how a DuckLake warehouse on object storage authenticates:

FieldDefaultDescription
type"s3"Secret type
key_id""Access key ID
secret""Secret access key
endpoint—host[:port], no scheme (MinIO, R2, …); unset = AWS default
region—Region
url_style—path for MinIO-style endpoints
use_ssl—true/false
scope—Pin the secret to a prefix, e.g. s3://bucket

Connections, inputs, and CDC

connections: entries are http (base_url, headers) or postgres (dsn). A Python model calls connection(name) while it is building. Sensitive header values and DSN credentials are redacted on GET /connections.

inputs: entries are DuckDB scans a model can FROM by name. format is parquet, csv, json, delta, or iceberg. path accepts ${date}, ${datetime}, and ${workspace}. connection is an http connection (sent as an httpfs secret) or the name of an engine secrets: entry. A model on any other engine that reads an input is a config error.

cdc: entries copy a Postgres logical slot into a @stream. Each names connection (a postgres connection), slot, publication, tables, and stream. interlace serve reads pgoutput. The stored LSN advances only after those offsets have been flushed. The slot and publication are created outside Interlace.

event_log_path, when set, appends one JSON object per operator event after the SQLite commit.

Environment Variable Interpolation

${VAR} anywhere in the file is substituted before YAML parsing — from the process environment first, then from a .env file next to interlace.yaml:

database: 'ducklake:postgres:${WAREHOUSE_DSN}'
  • Only the braced ${VAR} form is recognised (no $VAR, no ${VAR:-default})
  • Unset variables stay as literal ${VAR}; if one survives into the warehouse config, startup fails with the variable named — never a silent empty string
  • The .env parser accepts comments, blank lines, an optional export prefix, and quoted values; it never modifies your process environment

Environment Variables Read by Interlace

VariableEffect
INTERLACE_ENVDefault for --env
INTERLACE_QUACK_TOKENToken for quack: databases
PGHOST / PGSERVICESatisfy the Postgres host requirement