Environments
Separate development, staging, and production with dedicated environments. Test changes safely before deploying to production, with full isolation between stages.
dbt_janeanalytics_staginganalyticsWhy Environments Matter
Without environment separation, a developer testing a model change could accidentally affect production dashboards. dbdeux environments provide:
- Safe experimentation: Develop and test against sandbox warehouses without risk
- Staged promotion: Move changes from dev → staging → production with gates at each step
- Different credentials: Each environment connects to its own warehouse instance
- Independent configurations: dbt variables, targets, and schemas can differ per environment
Environment Types
Development
Your personal workspace for building and testing models:
- Connected to a development warehouse
- Changes are visible only to you
- Fast iteration with instant feedback
- No impact on other team members or downstream consumers
Per-Developer Schema
A development environment can give each teammate their own warehouse schema so people never overwrite each other's tables during feature-branch work:
- Each developer builds into their own schema (for example
dbt_jane,dbt_alex) - The schema name comes from a configurable template,
dbt_{username}by default - Works across all warehouse adapters (Snowflake, BigQuery, Redshift, and others)
- The environment wizard shows a live preview of the resolved schema for the current user
When you open the Variables tab of a development environment that uses a per-developer schema, dbdeux shows a clear notice with the exact schema your runs will build into (for example dbt_jane). The notice is explicit that this override wins over any schema variable you set below, so there is no confusion about where your seeds and models land.
Managed Dev Databases
For teams that want a full, isolated copy rather than just a separate schema, a development environment can provision a managed dev database: your own throwaway clone of a source database, created on demand.
- Governed by policy: Organization admins decide which connections (and optionally which specific databases) can be cloned. Anything without a policy cannot be cloned.
- Time-limited: Each clone has a lifetime (TTL) set by the policy, with a default and a maximum. When it expires, dbdeux cleans it up automatically so unused copies do not linger.
- Adapter-aware: dbdeux picks the most efficient clone strategy for each warehouse, so the copy is created the fastest way your warehouse supports.
- Works across warehouses: Available for Snowflake, Postgres, BigQuery, Databricks, MySQL, SQL Server, and Redshift. Adapters without a clone strategy simply show that cloning is not supported.
- Refresh or drop: Refresh your clone to pull the latest source data, or drop it early when you are done.
Sandbox
A shared, unlocked environment for open experimentation. A sandbox runs with its selected connection and this environment's variables, so it resolves the same way for everyone on the team.
- Uses the connection you point it at plus the environment's own dbt variables
- Best set to a shared visibility so the whole team works from one sandbox definition
- Not locked, so anyone with access can iterate freely
To create a sandbox, select Sandbox as the type in the environment wizard and choose its connection and variables.
Staging
A shared environment for integration testing and review:
- Connected to a staging warehouse with production-like data
- Used for validating pull requests before merging
- CI/CD can automatically run models here on every PR
- Reviewers can verify results before approving changes
Production
The live environment that powers your dashboards and reports:
- Connected to your production warehouse
- Changes arrive only after passing through dev and staging
- Scheduled runs execute here on your defined cadence
- Alerts and notifications monitor this environment
Each project has one Production environment. dbdeux enforces this so there is a single, unambiguous source of truth for what "production" means. That single production environment is what run guardrails, deferred builds, and impact previews compare against, which keeps promotion and safety checks predictable.
Configuration
Each environment can specify:
| Setting | Example |
|---|---|
| Connection | Which warehouse credentials to use |
| Target schema | analytics_dev, analytics_staging, analytics |
| dbt target | dev, staging, prod |
| Variables | Different values for {{ var('start_date') }} per environment |
| Thread count | More threads in production for parallel execution |
| Default dbt version | The dbt engine version runs in this environment use by default |
Default dbt Version
Each environment can set a default dbt version. That default is the version editor runs and scheduled jobs use unless you explicitly pick another one, so a team standardizes on a dbt version per environment without anyone having to remember to select it each time.
The default is surfaced everywhere the version matters, so it is never a hidden setting:
- The environment wizard and overview show the environment's default version
- The editor run bar shows and applies it, and still lets you override the version for a one-off run
- The job wizard and job detail show which version a scheduled job will inherit
Per-Environment Slimmer CI
An environment can also override Slimmer CI for pull requests that deploy to it: enable or disable CI for that environment (or inherit the project setting), and choose which deployment environment its pull requests are compared against.
dbt Variables
Each environment has its own dbt Variables editor, separate from environment variables. These are the --vars values that dbt injects into your Jinja templates via {{ var('my_var') }}.
How It Works
- Open Environments and select an environment
- Switch to the Variables tab
- In the dbt Variables section, enter your variables in YAML or JSON format:
start_date: "2024-01-01"
enable_snapshots: true
warehouse_size: large
- Click Save to persist the variables
The editor validates your input in real time and shows a count of the keys being saved.
Where Variables Are Applied
Once saved, dbt variables are automatically injected into:
- Manual runs from the IDE (Run, Compile, Build, Test)
- Scheduled jobs on this environment
- Slimmer CI builds triggered by PRs targeting this environment's branch
This means you can set different variable values per environment without changing your dbt code. For example:
| Variable | Development | Staging | Production |
|---|---|---|---|
start_date | 2024-06-01 | 2024-01-01 | 2023-01-01 |
enable_snapshots | false | true | true |
sample_pct | 10 | 100 | 100 |
Environment Variables vs dbt Variables
| Environment Variables | dbt Variables | |
|---|---|---|
| Used via | {{ env_var('MY_VAR') }} | {{ var('my_var') }} |
| Scope | Available to dbt and any subprocess | Passed as --vars to dbt only |
| Format | Key-value pairs with optional masking | YAML/JSON mapping |
| Typical use | Secrets, credentials, paths | Feature flags, date ranges, config toggles |
Both are set per-environment, so each stage of your pipeline can have its own values.
Extended Attributes (Connection Overrides)
Each environment can define Extended Attributes that override connection settings at runtime. These are free-form key-value pairs that deep-merge into the profiles.yml target, covering adapter knobs the structured connection form does not expose.
Common overrides
| Adapter | Useful overrides |
|---|---|
| Snowflake | threads, query_tag, client_session_keep_alive |
| BigQuery | maximum_bytes_billed, job_retry_deadline_seconds |
| Redshift / PostgreSQL | connect_retries, connect_timeout |
| Databricks | http_headers, connection_parameters |
Editor modes
- Structured editor: Add key-value pairs with typed values (string, number, boolean, JSON). Adapter-aware suggestions appear based on the environment's connection type
- Raw YAML toggle: Paste a raw YAML block (e.g., a
dbt Cloud extended_attributesblock ports straight in)
Safety guardrails
Identity and secret keys (account, password, private_key, host, etc.) are flagged inline and blocked from being saved as overrides. Overrides can only tune a connection, never repoint it.
A merged-target preview shows exactly how the overrides layer onto the dbt target so you can verify the final config before saving.
Environment Promotion
Move changes through environments with confidence:
- Develop on a feature branch in the dev environment
- Open a PR which automatically triggers a staging run
- Review the results, schema diff, and test outcomes in staging
- Merge to deploy to production on the next scheduled run (or immediately)
Environment Wizard
Create and edit environments through a guided side-drawer wizard:
- Vertical step rail walks you through name, type, connection, variables, and gates
- Type picker shows all available types (Development, Sandbox, Staging, Pre-production, Production) with descriptions
- Connection logo and org/project context are shown at each step so you always know where the environment will live
- The wizard cannot be accidentally dismissed by clicking outside the drawer
Auth-Aware Variables Step
The Variables step is tailored to the connection you picked, so you only fill in what that warehouse actually needs:
- Standard rows are prepopulated with the environment variable names for the connection's adapter and auth method, sourced from the selected connection only
- Snowflake key-pair connections show the key-pair variables (user, private key, optional passphrase) instead of a password field, with guidance on the expected format
- Blank environments can prepopulate variable names from the project's dbt target (names only, never values), preserving anything you have already typed as you switch targets. If the target cannot be found, the wizard warns you and recommends the connection-based flow rather than falling back silently
- Secret variables stay listed after they are saved, marked as set, so you can see which secrets already have a value without re-entering them
Variable Validation
When you validate an environment's variables against your project, references are grouped so you can act on them quickly:
- Missing: required variables referenced in your project but not supplied here
- Optional: references that use a default value (
env_var('NAME', 'default')), so they are safe to leave unset. A name used both with and without a default stays required - Unused: variables defined here that your project does not reference
- Mutually exclusive credentials (for example, Snowflake password versus key-pair) are treated as an either/or choice, so supplying one does not flag the other as missing
Clone an Environment
Rather than rebuilding a similar environment by hand, clone an existing one from its detail view. A side drawer lets you:
- Name the copy (it defaults to the source name with a
-copysuffix) - Choose the new environment's type (Development, Sandbox, Staging, Pre-prod, Production, Post-prod, or Custom)
- Carry the source environment's configuration and variables into the copy
Secret values are handled safely during a clone, so you never expose stored secrets by copying an environment.
Copy, Export, and Import Variables
The Variables tab makes it easy to move variables between environments and to work with them in bulk:
- Copy to environment: Copy this environment's variables straight into another environment in the same project
- Export to CSV: Download the variables as a CSV file. Secret values are never exported. Each secret keeps its key and is marked as a secret with an empty value, so a later import recreates the key and prompts you for a fresh secret
- Import from CSV: Paste or upload a CSV to add variables in bulk, using a header row that names the key, value, and secret columns
Environment Indicators
The UI clearly shows which environment you are working in:
- Color-coded headers (blue for dev, yellow for staging, red for production)
- Environment name displayed prominently in the IDE toolbar
- Confirmation prompts before running in production
- Branch-to-environment mapping shows where your branch will deploy