dbt seeds are CSV files committed to your dbt project repository that dbt loads directly into your data warehouse as tables. They provide a managed, version-controlled way to maintain small, static reference datasets — country codes, product categories, cost center mappings — without requiring an EL pipeline.
dbt seeds are CSV files stored in the seeds/ directory of a dbt project that dbt loads directly into the data warehouse as tables. They provide a version-controlled, reproducible way to manage small, static reference datasets — the lookup tables, mapping files, and code tables that every data model needs but that are too small to warrant an EL pipeline and too important to maintain manually.
What Seeds Are For
Seeds solve a specific problem: small, stable reference data that belongs in the warehouse alongside your transformed data, but that doesn't come from a source system loaded by Fivetran or Airbyte.
Common seed use cases:
- Country and region code mappings (ISO country codes to region names, timezone mappings)
- Fiscal calendar definitions (mapping calendar dates to fiscal periods, quarters, and years)
- Product category hierarchies (category codes to human-readable names and parent categories)
- Cost center and organizational mappings (cost center codes to department names and business units)
- Holiday calendars (date lookups for whether a given date is a business day)
- Exchange rate snapshots (monthly average rates for historical currency conversion)
- Test or validation data (known-good values for testing downstream models)
These are reference tables that analysts need when joining or filtering, that change infrequently, and that have no natural home in any source system.
How Seeds Work
Seeds are CSV files with a header row and data rows. Running dbt seed:
1. Reads each CSV file in the seeds/ directory
2. Creates a table in the data warehouse (same name as the CSV file, minus the extension)
3. Loads the CSV data into that table
The table is created in the schema configured for seeds (typically the same schema as your other models, or a dedicated seeds schema). Once loaded, seeds are treated like any other table in the warehouse — you reference them with ref() in downstream models: {{ ref('country_codes') }} joins the country_codes seed table.
Seeds are re-run only when explicitly invoked with dbt seed — not during dbt run. This means seeds are stable references that don't change unless you explicitly update the CSV and re-seed.
Seed Configuration
Seeds support configuration in dbt_project.yml and in a separate properties YAML file in the seeds/ directory. Configuration options:
Column data types can be specified to override dbt's inferred types: dates that come through as strings in CSV need explicit cast to date type. Set column_types in the seed config to force the correct type.
Schema and database overrides allow seeds to be loaded into a different schema than the default, useful when reference data should be isolated from transformed model outputs.
Quoting configuration handles column names that are case-sensitive or contain special characters.
Seeds vs. Sources vs. Models
Understanding when to use each:
**Seeds:** Small, static reference data that you own and maintain as CSV files in the repo. Changes by updating the CSV and running dbt seed. Appropriate when: the data has no source system, the data changes rarely (quarterly or less), the dataset is small enough to version in git (under a few thousand rows as a rule of thumb).
**Sources:** Raw data loaded by EL tools into the warehouse. You declare them in YAML but don't control the data — it comes from external systems. Use source() to reference them in staging models.
**Models:** Transformed data produced by dbt SELECT statements. The output of your transformation logic. Reference with ref().
A country code mapping maintained by your team that changes once a year: seed. A country dimension loaded from your CRM system via Fivetran: source. A country dimension enriched with regional groupings your business defines: model.
Seeds in Production
Seeds are appropriate for truly static reference data in production. They are not appropriate for data that updates frequently — a seed that needs daily updates requires dbt seed to run daily, adding latency and operational complexity. For frequently-changing reference data, a proper source (a database table loaded by an EL tool) is the right choice.
Some teams use seeds for test fixtures — small datasets that represent known states used to test whether downstream models produce expected outputs. This is a valid use case separate from production reference data.
Seeds are committed to the git repository, giving them full version history. When the country code mapping is updated, the change is in a pull request, reviewed, and merged — the same review process as any other code change. This is the key advantage of seeds over maintaining reference data as manually-managed database tables.
Our data architecture services includes dbt project design, reference data architecture, and data warehouse implementation. Contact us to discuss your dbt implementation.
A former Microsoft data architect audits your data foundation, identifies your top priorities, and sends you a written plan. Free. No pitch.
Book a Call →