dbt Seeds
Seeds are CSV files that you store inside your dbt project and load into the warehouse as tables. They are ideal for small, rarely changing datasets that you want to version-control alongside your models. Seeds work exactly like lookup tables that your other models can reference using ref().
What Seeds Are Good For
Think of seeds as the reference data that makes your business logic meaningful:
- Country code to country name mappings (
US→United States) - Product category hierarchies
- Marketing channel groupings (50 traffic sources → 5 categories)
- Internal cost tables (shipping cost per region)
- Exchange rate tables for small date ranges
- Test fixtures for development environments
Creating a Seed File
Place any CSV file inside the seeds/ folder. The file name becomes the table name in the warehouse.
seeds/ country_codes.csv marketing_channels.csv product_categories.csv
seeds/country_codes.csv
code,country_name,region US,United States,North America IN,India,Asia Pacific GB,United Kingdom,Europe DE,Germany,Europe BR,Brazil,Latin America AU,Australia,Asia Pacific JP,Japan,Asia Pacific FR,France,Europe
seeds/marketing_channels.csv
utm_source,channel_group,paid google,Paid Search,true bing,Paid Search,true facebook,Paid Social,true instagram,Paid Social,true organic,Organic Search,false direct,,false email,Email,false referral,Referral,false
Loading Seeds
Run this command to load all seed files into your warehouse:
dbt seed
dbt creates one table per CSV file in your target schema:
$ dbt seed Running with dbt=1.8.3 Found 2 seeds 1 of 2 START seed file dbt_dev.country_codes ......... [RUN] 1 of 2 OK loaded seed file dbt_dev.country_codes ..... [INSERT 8 in 0.3s] 2 of 2 START seed file dbt_dev.marketing_channels .... [RUN] 2 of 2 OK loaded seed file dbt_dev.marketing_channels [INSERT 8 in 0.2s]
Referencing Seeds in Models
Reference seeds in your models using ref() — the same function you use for other models:
-- models/fct_sessions.sql
select
s.session_id,
s.utm_source,
s.page_views,
mc.channel_group,
mc.paid
from {{ ref('stg_sessions') }} s
left join {{ ref('marketing_channels') }} mc
on s.utm_source = mc.utm_source
-- models/dim_customers.sql
select
c.customer_id,
c.full_name,
c.country_code,
cc.country_name,
cc.region
from {{ ref('stg_customers') }} c
left join {{ ref('country_codes') }} cc
on c.country_code = cc.code
Seeds appear in the DAG as parent nodes of the models that reference them, just like source tables.
Configuring Seeds
Configure seeds in dbt_project.yml or in a YAML file inside the seeds/ folder.
Setting Column Types
By default dbt infers data types from the CSV content. Override type inference using configuration:
# dbt_project.yml
seeds:
my_project:
country_codes:
+column_types:
code: varchar(2)
country_name: varchar(100)
region: varchar(50)
Setting Schema for Seeds
seeds:
my_project:
+schema: reference_data
This places all seeds in a separate schema named reference_data rather than your default schema. Useful for keeping reference data separate from transformed models.
Configuring per Seed File
seeds:
my_project:
marketing_channels:
+schema: reference_data
+column_types:
paid: boolean
country_codes:
+schema: reference_data
+column_types:
code: char(2)
Refreshing Seed Data
When you update a CSV file and rerun dbt seed, dbt inserts new data but preserves the existing table structure. To completely rebuild the table from the updated CSV, use the --full-refresh flag:
dbt seed --full-refresh
Use --full-refresh whenever you add new columns to a seed CSV or change a column's data type.
Running Seed + Models Together
The dbt build command runs seeds, models, tests, and snapshots together in dependency order:
dbt build
Seeds load before any models that reference them. You can also target seeds explicitly:
# Run only the seeds dbt seed # Run a specific seed dbt seed --select country_codes # Run a seed and models that depend on it dbt build --select country_codes+
When NOT to Use Seeds
Seeds have limitations that make them unsuitable for certain data:
Use Seeds When: Do NOT Use Seeds When: -------------------- ---------------------- Row count < 10,000 Row count > 10,000 Data changes rarely Data changes daily/hourly Data is for lookup only Data needs complex joins before use Simple flat structure Multi-level nested structure
For large or frequently updated reference data, load it via your ingestion tool (Fivetran, Airbyte, etc.) and declare it as a source. Seeds are for small, stable reference tables only.
Seeds in Documentation
Add descriptions to seed files and their columns in a YAML file inside the seeds/ folder:
# seeds/schema.yml
version: 2
seeds:
- name: country_codes
description: "ISO 3166-1 alpha-2 country codes with region groupings"
columns:
- name: code
description: "Two-letter ISO country code (e.g. US, IN, GB)"
- name: country_name
description: "Full English country name"
- name: region
description: "Continent-level region grouping for reporting"
These descriptions appear in the dbt documentation site alongside your model documentation.
