Is dbt Still Free? A Practical Guide for Small Marketing Data Teams
Data Engineer and Co-founder, martechdevs
Last updated 12 min read
Yes, dbt still has free local options. The important distinction is between the engine you run, the hosted platform you use and optional paid services. For a marketing team, the bigger question is whether dbt will turn scattered SQL into definitions people can test, change and trust.
Last updated: 9 October 2026.
You do not need a large data team to benefit from that discipline. You do need someone who can own the SQL and its business meaning. Installing dbt will not decide what counts as a qualified lead, resolve conflicting customer IDs or recover history you never collected.
Start with one recurring decision, such as where qualified pipeline is coming from. Build the smallest dependable model for it. Expand when another output needs the same underlying logic.
What changed with dbt v2
dbt v2 reached general availability in September 2026. The full distribution, previously called Fusion, is now called dbt. The Apache 2.0 subset previously called dbt Core v2 is now dbt OSS. Both can run locally without a paid platform subscription; they have different feature and licensing scopes. dbt's distribution explanation
The older Python-based v1 line remains supported. Do not infer that an existing v1 project stopped working when the names changed. Before upgrading, check your adapter, authentication method, packages and deprecated project settings against the current upgrade guide. Upgrading to v2
For licensing, use the distribution-specific documents. dbt OSS is Apache 2.0; the full dbt distribution includes proprietary components under the dbt Product Licensing Agreement. The current licensing FAQ also says the previous free-user cap for the VS Code extension no longer applies. Licensing FAQ
The product agreement contains conditions for use and redistribution. A free local installation and permission to embed a product in a service for other customers are separate questions. Read the agreement for that second use case. dbt Product Licensing Agreement
The Fivetran combination did not remove those free distributions. It also does not mean you must buy Fivetran ingestion to run dbt. Choose ingestion according to your source requirements, and transformation according to how you maintain and publish trusted models.
What a small team pays for the hosted platform
Current public pricing lists Developer as free for one developer, one project and 3,000 successful models built monthly. Starter is $100 per developer per month, supports up to five developer seats and includes 15,000 successful models built per account per month. Its allowance is not multiplied by the number of seats. Enterprise tiers use custom pricing. dbt pricing
Under the documented Developer terms, exceeding the allowance cancels subsequent runs until the monthly reset or an upgrade. Starter permits additional usage and bills it in arrears. Unused included models do not roll forward, and legacy entitlements can differ. Check the account's actual terms before planning production around a generic pricing page. Plans and billing
Keep four costs separate: platform seats and usage, optional services, warehouse execution, and internal operating effort. Two Starter seats illustrate a $200 monthly seat charge before other consumption. A free local engine still needs a scheduler, credentials, logs, upgrades and someone responding to failed jobs.
A model file is not a monthly billing unit
Successful models built counts eligible executions in deployment environments through dbt orchestration, including CI and API-triggered jobs. Views, tables and incremental models count; development-environment builds, tests, seeds, snapshots and ephemeral models do not. Successful models inside a later-failing job still count. The Analyst seat type is unavailable for new purchase, which is different from saying every existing Analyst licence disappeared. How pricing works
Here is an illustrative schedule, assuming ten eligible models are actually rebuilt on every run:
- Daily for 30 days:
10 × 30 = 300successful builds. - Hourly for 30 days:
10 × 24 × 30 = 7,200successful builds. - Add 20 CI runs that each rebuild ten models: another 200 builds.
The hourly version reaches 7,400, before retries or additional jobs. That exceeds the standard Developer allowance even though the repository contains only ten models. It fits the stated Starter build allowance, but seats, optional services and warehouse costs remain separate.
Do not buy a larger plan until you establish why those models need to rebuild hourly.
dbt State has a different meter
dbt State can reuse work through skipping, cloning and test reuse. It charges $0.094 per daily active target table, or DATT, after applicable free-trial terms. A target includes models, seeds, snapshots and distinct tests; database and schema identify its scope. Repeated reuse of the same target within one UTC day counts once. Reused models do not also count as successful models built under the hosted platform meter. dbt State usage
For an original illustration, suppose ten model targets and twenty test targets are each reused on all 30 days in one environment. That is 30 × 30 = 900 DATT and $84.60. If an equivalent set in a separate schema is also reused each day, the illustration doubles to $169.20. It does not remain one global set of thirty objects.
Compare that charge with measured warehouse savings on the same workload. If the first scenario saves an illustrative $200 in compute, the difference is $115.40 before operating costs. If it saves $80, the net difference is negative $4.60. These are arithmetic examples, not observed savings or a prediction about your project.
A small project may be cheaper with a sensible schedule and no State service. A large repeatedly selected graph may justify reuse. Measure both cases while keeping output freshness and correctness equivalent.
Decide whether you need dbt yet
dbt is useful when business logic has dependencies, gets reused and needs controlled changes. Typical signals include several dashboards redefining revenue, a growing chain of scheduled queries, or a fix that quietly changes three unrelated reports.
A SQL model is a query stored in the project. dbt builds it into the configured warehouse relation, and ref() establishes dependencies between project resources. That gives you a graph you can test and maintain rather than a collection of copied queries. SQL models
You may not need it yet if one maintained query answers one stable question and the warehouse scheduler already handles it adequately. Document that query's inputs, owner, assumptions and alerting. Introduce dbt when shared logic and safe changes become real needs.
Do not introduce it to compensate for missing ingestion. First establish the source data and identifiers your output requires. The marketing data warehouse guide explains that foundation.
Ten useful marketing models, with a clear grain and test
These are a starting design for a B2B SaaS team, not ten mandatory files for every company. Build the models needed by your first decision. More source-specific staging may be necessary; billing, product and CRM schemas do not become interchangeable because their fields have similar names.
1. `stg_ads__daily_spend`
Keep one row per platform, advertising account, campaign, source reporting date and currency at the chosen reporting breakdown. Standardise names and types while preserving original IDs and timezone meaning. Test that the composite grain is unique and that account and currency are present. Extra device or placement breakdowns must be aggregated deliberately before this grain holds.
2. `stg_crm__contacts`
Keep one current row per source portal and contact ID. Preserve the application user ID when legitimately available, along with deletion and merge indicators. Test the namespaced key for uniqueness and missing values. An email address is an attribute, not a reliable replacement for the record key.
3. `stg_crm__deals`
Keep one current row per portal and deal ID, with stage, amount, currency and associations handled explicitly. Test uniqueness and accepted stage mappings. Quarantine unknown currencies instead of silently treating them as your reporting currency. This model answers current-state questions; it cannot establish an old stage on its own.
4. `stg_billing__invoices`
Keep one row per billing account and invoice ID. Preserve invoice state, currency, amounts and relevant timestamps. Test the key and approved status values. An invoice total, a paid amount, recognised revenue and MRR are different measures. Choose the one your output needs and account for refunds and adjustments separately.
5. `stg_product__events`
Keep one row per source and event ID, including occurrence time, ingestion time, user ID and account ID where available. Test duplicate delivery and required event properties. Retain enough timing information to diagnose delayed events. Use the tracking plan to define which actions represent useful product behaviour.
6. `bridge_customer_identifiers`
Map a namespaced source identifier to an internal person or account, with evidence and effective dates where needed. Test for conflicting simultaneous assignments, not just duplicate rows. A person can belong to several accounts, and two systems can legitimately issue the same numeric ID. See the identity resolution design before joining everything through email.
7. `fct_deal_stage_changes`
Keep one verified stage-transition event per deal, with source event identity or an explicitly defined sequence. Preserve effective time and observed time if both exist. Test duplicated transitions and invalid ordering. If you only have periodic observations, label their timing uncertainty; a nightly snapshot cannot reveal every transition between observations.
8. `fct_acquisition_spend`
Produce additive spend at an agreed campaign, reporting date, channel and reporting-currency grain. Apply documented channel mappings and currency conversion rules. Test the grain, mapping coverage and reconciliation against source totals before conversion. Keep an explicit unmapped category so incomplete taxonomy does not make spend disappear.
9. `fct_qualified_deals`
For this design, keep one row per deal's first valid qualification, carrying its qualification date, acquisition-channel assignment, amount at qualification and reporting currency. Requalification episodes would require a different grain. Test one row per namespaced deal and preserve missing acquisition evidence as Unattributed. Document the attribution rule without presenting it as proof of causal impact.
10. `mart_growth__channel_day`
Aggregate spend and qualified deals independently, then combine them by reporting date, channel and currency. Test that final grain and reconcile both measures to their inputs. This produces a reusable daily output for budget discussions without multiplying spend by the number of deals. Call the value qualified pipeline, not cash revenue or marketing ROI.
Prevent a common reporting error in the final model
Suppose two campaigns in Paid Search spend $40 and $60 on one reporting date. Two deals qualify that day with values of $5,000 and $7,000.
Joining campaign rows directly to deal rows by date and channel creates four rows. The resulting sums are $200 spend and $24,000 pipeline, twice the correct amounts. A successful SQL run does not make the result correct.
The following original model assumes the two upstream facts follow the contracts above. Dates, channel labels and currencies must already be normalised and non-null. Unattributed preserves unknown acquisition evidence. Save the model as models/marts/mart_growth__channel_day.sql in your project:
with spend as (
select
report_date,
channel,
reporting_currency,
sum(spend_amount) as spend_amount
from {{ ref('fct_acquisition_spend') }}
group by report_date, channel, reporting_currency
),
qualified as (
select
qualification_date as report_date,
channel,
reporting_currency,
count(*) as qualified_deals,
sum(amount_at_qualification) as qualified_pipeline
from {{ ref('fct_qualified_deals') }}
group by qualification_date, channel, reporting_currency
),
reporting_keys as (
select distinct report_date, channel, reporting_currency
from (
select report_date, channel, reporting_currency from spend
union all
select report_date, channel, reporting_currency from qualified
) combined_keys
)
select
k.report_date,
k.channel,
k.reporting_currency,
coalesce(s.spend_amount, 0) as spend_amount,
coalesce(q.qualified_deals, 0) as qualified_deals,
coalesce(q.qualified_pipeline, 0) as qualified_pipeline
from reporting_keys k
left join spend s
on k.report_date = s.report_date
and k.channel = s.channel
and k.reporting_currency = s.reporting_currency
left join qualified q
on k.report_date = q.report_date
and k.channel = q.channel
and k.reporting_currency = q.reporting_currencyThe union of keys preserves days and channels with spend but no qualified deals, or qualified deals but no recorded spend. It does not manufacture evidence that a zero-spend channel caused the pipeline.
The example's grain matters more than its naming style. If a deal can appear twice in fct_qualified_deals, fix that fact before trusting count(*). If historical amounts are unavailable, disclose that limitation instead of substituting today's amount without explanation.
Test meaning as well as column shape
dbt data tests can assert uniqueness, non-null values, accepted values and relationships; custom SQL tests return failing records. Passing those checks establishes the assertions you wrote, not every possible business property. Data tests
For example, place this original configuration under your model path:
models:
- name: fct_qualified_deals
description: One row per deal at its first valid qualification.
columns:
- name: deal_key
data_tests:
- not_null
- unique
- name: qualification_date
data_tests:
- not_null
- name: channel
data_tests:
- not_null
- name: reporting_currency
data_tests:
- not_null
- name: amount_at_qualification
data_tests:
- not_nullAlso assert the final composite grain and input-to-output amount reconciliation. Use small fixtures for the two-campaign/two-deal case, a spend-only channel and an unattributed deal. dbt unit tests support checking SQL logic against static inputs before building the full production model. Unit tests
In this article's local SQL fixture, the aggregated query produces the correct $100 spend, two deals and $12,000 pipeline for Paid Search. That verifies the illustrated join logic. It does not certify your warehouse dialect, dbt adapter, production source contracts or attribution policy.
Assign actions to failures. A missing currency or duplicate deal key should prevent publishing this output. A new channel mapping might remain in a visible unmapped bucket while an owner investigates. Silently dropping the record makes a cleaner dashboard and a worse decision.
Keep costs and operations proportional
Schedule from the reporting deadline backwards: complete ingestion, transformation, tests, then publication. Hourly orchestration adds little value if your required upstream extract arrives once daily.
For unchanged ordinary views, consider excluding unnecessary rebuilds while retaining their tests and a deployment path for changed view definitions. Dynamic SQL that depends on source values needs extra care. dbt's optimisation guide distinguishes those cases and explains selective builds and lag tolerance. Cost optimisation
Start with simple materialisations and inspect actual query cost before adding incremental complexity. A faulty incremental filter can miss late updates while producing a reassuringly small bill. Document how a complete rebuild would work and what it would cost. The dbt implementation troubleshooting guide covers historical backfills, late corrections and the difference between code-change selection and data refresh.
Use separate development targets and production credentials, version-controlled changes, an owner for alerts and a defined last-complete reporting timestamp. These practices are useful whether you buy hosted orchestration or operate dbt yourself.
MCP can help an AI client explore metadata or use supported dbt tools. The self-hosted server supports local development commands; remote access focuses on platform capabilities, with tool availability depending on underlying API entitlements. An MCP connection does not replace these models or their definitions. dbt MCP documentation
Before making the first model a production dependency:
Checklist
- Name its business question, grain, cutoff and owner.
- Reconcile source records, currencies and identifiers.
- Test duplicate, missing, late and unmapped cases.
- Forecast eligible builds, optional services and warehouse cost separately.
- Confirm the selected runtime, adapter, packages and licence.
- Set a deployment, failure-response and recovery procedure.
- Have the decision-maker verify the output against known examples.
If you need help turning a fragile marketing report into a maintained model, our data warehouse and CDP service can define the source contracts, implement the useful transformations and set up the checks that keep them trustworthy.
Questions people ask
Is dbt still free in 2026?
Yes. Free local distributions remain available, with different licensing and feature scopes. The hosted Developer plan also has a free allowance. Warehouse compute, optional paid services and your team's operating work are separate from the engine's price.
What is the difference between dbt Core and dbt Cloud now?
Those older labels do not fully describe the current choices. The Python v1 line remains supported; v2 has the full dbt distribution and the Apache-licensed dbt OSS subset. The hosted dbt platform supplies managed development and orchestration with plan limits. Choose runtime and hosting separately.
Does every test use my hosted model-build allowance?
Tests do not count as successful models built under the documented platform meter. Reused tests can count under dbt State's separate DATT meter, and executing tests can consume warehouse resources. One usage counter does not describe the whole cost.
Do I need dbt State for a small project?
No. Start with a schedule and model selection that meet the business deadline. Evaluate State when reuse could save meaningful compute or operating work, and compare its measured charges with the avoided cost. Keep freshness and correctness equal in that comparison.
Can a marketing manager use dbt without an engineer?
A SQL-capable manager can own a small project, but someone must maintain its deployment, tests, credentials and definitions. AI assistance can help draft code; it cannot verify an undocumented qualification rule. If nobody can investigate a failed model, keep the system simpler or assign that responsibility first.
Sources
Written by
Jafrin Akter AloData Engineer and Co-founder, martechdevs
Jafrin Akter Alo is a data engineer and co-founder of martechdevs, where the team has delivered 74+ martech, data and growth stack implementations.