← All writing

dbt State is free forever: 1,000 DATT a month is worth $94, and the rest is on your warehouse bill

Two old books stacked on each other, a pale purple tassel bookmark tucked between the pages of the top one and hanging over the spine
Cover · Source: Abigail Ybarra / Unsplash
Contents
  1. It rebuilds only when the result would change
  2. Three environments share one state, with prod as the baseline
  3. The free tier is worth at most $94 a month

On October 20 dbt Labs made dbt State free forever for self-hosted dbt users: 1,000 DATT a month, no card, no contract.1 dbt State is a separate service that shares state between dbt runs so later builds can reuse earlier results. It works with Snowflake, BigQuery, Databricks and Redshift, from self-hosted dbt, the dbt platform, Airflow or Dagster, but it needs a dbt account login.14 dbt 1.13 and v2 support it natively; 1.7 to 1.12 use a plugin.4

DATT, daily active target tables, is the billing unit. If dbt State skips, clones or reuses a test result for a target on a given UTC day, that target is one DATT, however many times it is reused that day. Seeds, snapshots and models are targets, and so is every test: a model with not_null and unique tests is three targets. Past the allowance, each DATT costs $0.094.3 dbt platform plans get allowances too, 1,000 on Starter and 2,000 on Enterprise, until March 31, 2027.3

It rebuilds only when the result would change

Before each node runs, dbt State checks logic and data. If the rendered SQL changed, it rebuilds. If the SQL is the same, the table exists in this schema, and either upstream data hasn’t changed or the last build is still inside lag_tolerance (45 minutes by default), it skips. If the table is missing here but another environment has one with the same logic and fresh data, it clones that. Otherwise it builds as usual and defers unselected upstream nodes.2 In the docs’ example, a second run of a 12-model project reuses all 12 and estimates 17.77 seconds saved.7

What leaves your environment is metadata: last-modified timestamps and hashes of your SQL. The service never connects to the warehouse and runs on a single US multi-tenant instance.2 Teams under data-residency rules should clear that first.

Three environments share one state, with prod as the baseline

First, how the three relate. Prod, staging and dev run on their own, in no particular order. They share one state record in dbt State and, by default, all measure against prod.6 Prod builds tables on schedule; when staging or dev needs an upstream table, and prod’s copy has the same logic and fresh enough data, it reads or clones that copy instead of building its own.2

FIG.1Three environments share one state record, with prod as the baseline: when staging or dev lacks an upstream table, it reads or clones prod's. There is no order between them.

Prod saves repeated builds. Before each scheduled run, dbt State checks the record and skips tables whose SQL and upstream data haven’t changed. If upstream keeps changing, lag_tolerance sets a grace period; the docs suggest starting at 4 hours in prod, so a downstream model rebuilds at most every 4 hours.4 Frequent jobs gain most, because a table reused all day is still one DATT. Set allow_clones: false on the prod target so no other environment’s tables get cloned in and the baseline stays clean.5

Staging and CI save build volume on every PR. A PR usually touches a few models. With state:modified+, dbt State compares each node with its last run in prod and builds only real logic changes plus what sits downstream, reading every other upstream table from prod. Teams that treat staging as the reference can set defer_to_target: staging.6

Dev saves waiting. When you edit one model in your own schema, its upstream tables often don’t exist there yet. In the docs’ example, running only customers in a fresh dev schema fails without dbt State because upstream tables are missing; with it, upstream reads from prod, and an unchanged model is simply cloned from prod.7 The docs suggest a 7-day tolerance outside prod,4 since slightly older data is fine for development.

The free tier is worth at most $94 a month

1,000 × $0.094 is $94 a month, $1,128 a year. That is the most the free allowance saves directly.

Per day it is about 33 targets, with tests counted one by one. With a 30-day month and the list price, fees climb with the number of targets reused each day:

FIG.2Targets reused per day against the monthly dbt State fee, after the 1,000 free DATT. Assumes a 30-day month at $0.094 per DATT.

On the free plan, hitting the limit costs nothing, but reuse stops until the 1st of the next month,3 so a mid-sized production project can fall back to full rebuilds halfway through the month. The allowance suits personal dev, CI and small projects. For production, add a card for pay-as-you-go or sign a prepaid commit.1

The real saving is warehouse compute, and the test is simple: on the day a target is reused, the rebuild you avoided must cost more than $0.094. Large tables and incremental models in hourly jobs win easily. A view or test that builds in seconds still costs $0.094 to reuse. dbt Labs’ only savings figure is a customer quote: Virgin Media O2 says job run time and warehouse compute both fell 25%, with no baseline given.1 A safer path is to run a month inside the allowance, read the real DATT count under Billing & Usage,3 and set it against what your warehouse bill actually dropped.

References

  1. dbt State now available free forever, dbt Labs Blog
  2. About dbt State, dbt Docs
  3. dbt State usage, dbt Docs
  4. Setting up dbt State, dbt Docs
  5. dbt State configurations, dbt Docs
  6. Configure deferral, dbt Docs
  7. dbt State examples, dbt Docs

Comments