0%
(updated )5 min read🟢BeginnerFivetran

Fivetran MAR: The Invoice That Doubled, and the Credits You Still Pay

Monthly active rows surprise you, warehouse writes have their own bill, a custom extractor can beat a connector, and Fivetran still does not replace dbt.

D
Dinesh ChandraSenior Data & AI Engineer · SnowPro Certified
Illustrated overview of Fivetran MAR: The Invoice That Doubled, and the Credits You Still Pay
  • ✓MAR counts distinct primary keys that changed in the month. History tables multiply it.
  • ✓Destination writes burn warehouse credits even when the connector “just synced.”
  • ✓A custom extractor or Debezium wins when one fat source dominates the invoice.
  • ✓Fivetran lands raw. Grain, tests, and metrics stay in dbt.
  • ✓Monitor row counts and schema diffs. Sync success is not freshness.
Table of contents

The Fivetran invoice landed at $18,400. The previous three months had been $4,100 to $4,600. Nobody had added a source. Someone had enabled Salesforce history tables on an existing connector because an analyst wanted field-level audit. Monthly active rows jumped. Snowflake credits for that destination jumped with them: Fivetran was merging wide history into the warehouse every 15 minutes. Two bills. One checkbox.

MAR is not “rows in the table.” It is distinct primary keys that Fivetran saw change in the billing month, with their rules for how history and multi-table connectors count. I model it before I turn a connector on. I did not, that month.

What actually increments MAR

A quiet reference table that updates 200 keys a month is cheap. A chatty events table, or history enabled on every Salesforce object, is how you discover pricing. Re-syncs after a schema change can touch keys again. I treat a full re-sync as a budget event, not a click.

flowchart LR
  src["SaaS / DB"] --> ft["Fivetran"]
  ft -->|"MAR invoice"| bill1["Fivetran bill"]
  ft --> wh["Warehouse writes"]
  wh -->|"compute + storage"| bill2["Credits / slots"]
  wh --> raw["Raw / staging"]
  raw --> dbt["dbt models"]

Two meters. The connector fee and the warehouse write. History tables hit both.

-- Destination-side: what did Fivetran write yesterday?
-- Snowflake example; adjust to your account usage views.
SELECT
    table_name,
    sum(row_count) AS rows_approx,
    max(last_altered) AS last_altered
FROM snowflake.account_usage.tables
WHERE table_schema = 'FIVETRAN_SALESFORCE'
  AND deleted IS NULL
GROUP BY 1
ORDER BY 2 DESC
LIMIT 30;

-- Volume band on a sync-critical table (same idea as Airbyte).
SELECT count(*) AS rows_24h
FROM raw.salesforce.opportunity
WHERE _fivetran_synced >= dateadd('hour', -24, current_timestamp());

I page if rows_24h is zero on a weekday or 10× the 30-day median. A successful connector with zero destination rows is the same silent outage as Airbyte’s green check.

Warehouse credits: Fivetran uses a warehouse you sized. Fifteen- minute syncs on a Large, all day, are a second invoice. I pin a dedicated Small/Medium, auto-suspend of 60 seconds, and I do not share it with dbt. dbt incremental models should not fight the loader for slots — see incremental models.

Custom extractor versus connector

For long-tail SaaS (support tools, HRIS, a survey product) I buy the connector. Engineer-hours to chase pagination and OAuth expire faster than MAR. For one Postgres that already has CDC habits, I price Debezium against MAR at peak keys. At 80 million active keys a month, we moved that source off Fivetran and kept Fivetran for the SaaS tail. The invoice became explainable.

A Python extractor I own is cheaper only if I also own retries, schema drift, and on-call. I have built three. Two were a mistake. The third replaced a connector that re-synced 12 million keys after every nested JSON change.

You still need dbt

Fivetran transformations are not a metrics layer. I leave them off. Raw tables get _fivetran_deleted and _fivetran_synced. Silver interprets those flags. Soft deletes that disappear in a hard DELETE break incrementals. Mixing “net ARR” into the connector is how you cannot test grain in CI.

-- Silver: honor the delete flag. Do not hard-delete in raw.
SELECT
    id,
    amount,
    stage_name,
    _fivetran_synced AS synced_at,
    _fivetran_deleted AS is_deleted
FROM raw.salesforce.opportunity
WHERE _fivetran_synced >= dateadd('day', -3, current_date());

I estimate MAR in the connector PR the same way I estimate a warehouse size: last month’s distinct keys, times history if enabled, plus a 30 percent buffer for a re-sync. If I cannot write that number, I do not enable the table.

Pitfalls

History on every object “for audit.” Audit two objects in dbt snapshots. History on forty objects is an MAR event and a credit event. The checkbox is not free.

Sharing the Fivetran warehouse with dbt. Loader MERGE and model MERGE queue each other. Pin a dedicated warehouse, auto-suspend 60 seconds, and keep it off the BI route.

A full re-sync on Friday afternoon. Distinct keys all count again. Schedule it, warn finance, and watch destination credits the same hour.

Building a custom extractor for a long-tail SaaS. You will rebuild OAuth and pagination. Buy the connector. Save custom work for the one source that dominates the invoice.

Treating sync success as freshness. Zero destination rows on a weekday is the outage. Count them.

Enabling a connector in prod to “see the schema.” Use a dev destination and a table allow-list. The first sync against prod is when MAR starts. I have paid for a week of exploration that should have been a sandbox.

I keep a spreadsheet with connector, estimated MAR, history on/off, destination warehouse size, and owner. Ugly. It is how $18k becomes a line item instead of a surprise. Schema diffs still go to the same owner — a silent column type change is a contract break, not a Fivetran feature. I review that sheet when the invoice arrives, not a month later.

FAQ

What is a monthly active row? A unique primary key Fivetran touched that month. History tables and full resyncs inflate it. Read the connector’s MAR rules before you enable extras.

Does Fivetran replace dbt? No. It extracts. You still model grain in dbt. See Airbyte vs Fivetran. Hub: Fivetran.

Can I turn history on “just in case”? Only on objects you snapshot on purpose. History for every SaaS table is how $18k happens.

Where do schema changes go? To the owner of the destination model, as a contract break — not as a silent type change.

Destination credits are the second invoice

MAR is Fivetran’s meter. Snowflake (or BigQuery, or Redshift) still bills the merges. A 15-minute sync of wide Salesforce history is a warehouse job you did not write and cannot EXPLAIN as easily as a dbt model. I put the destination warehouse size and the sync frequency on the same spreadsheet as MAR. Slowing a chatty connector from 15 minutes to hourly has cut credits more than dropping a small source.

After a schema change I treat a full re-sync as a budget event. It touches keys again. It also rewrites the destination. See data contracts when the type change is the real incident.

The history-table incident: we disabled history on objects we did not use for SCD2, moved the two objects we did need to a dbt snapshot, and put a monthly MAR estimate in the connector PR template. $18k was a surprise. The next checkbox will not be. Fivetran is a good extractor. It is a bad place to hide a second warehouse and a worse place to hide the model.

Share this post:X / TwitterLinkedInRedditWhatsApp
D

Dinesh Chandra

Senior Data & AI Engineer · SnowPro Core & Gen AI Certified

4+ years building production data platforms on Snowflake, Databricks, AWS, and Azure. I write from hands-on experience with Medallion architectures, dbt, Airflow, PySpark, and Snowflake Cortex AI. Every tutorial on this blog reflects real pipeline decisions — not documentation rewrites.

Read more about the author →

Search DataLane

↑↓ navigate↵ openesc close