
What is CDC in data engineering? Change data capture explained
What is CDC in data engineering? Learn how change data capture records database changes, differs from ETL and incremental loading, and when to use it.
A practical Fivetran migration guide for moving PostgreSQL to BigQuery with Bruin and ingestr. Validate parity, reduce MAR-based spend, and run a governed open-source data ingestion pipeline.

Arsalan Noorafkan
Developer Advocate

Quick answer: if a PostgreSQL-to-BigQuery Fivetran connector is processing 20 million billable monthly active rows (MAR) each month, a rough $1,500 monthly bill is a reasonable migration trigger. With Bruin and ingestr, the software cost can be $0 when you run the open-source tools locally or in your own CI. A small self-managed server adds only its infrastructure cost, while a lightweight Bruin Cloud workload can stay below $100 a month when its actual memory-hour usage stays small.
That is not a promise that every 20 million-row database will cost exactly the same. Fivetran bills connections by MAR: distinct source records inserted, updated, or deleted during a calendar month. Twenty million rows sitting in PostgreSQL is not automatically 20 million MAR. Neither is a row that changes ten times in the same month, which Fivetran counts once for MAR. Check Fivetran's current pricing documentation and your account's estimator before treating any number here as a quote.
But the direction is clear. If the workload is a straightforward database replication job, you do not necessarily need a per-row managed connector bill to move it reliably.
Here is the deliberately simple scenario behind this guide:
| Detail | Example |
|---|---|
| Source | Production PostgreSQL |
| Destination | BigQuery |
| Monthly change volume | 20 million billable MAR |
| Fivetran cost model | Roughly $1,500/month in this example |
| Migration target | A code-reviewed Bruin pipeline using ingestr |
| First cutover destination | An isolated BigQuery v0 schema, not the live Fivetran table |
The cost comparison is about the ingestion layer. Your existing BigQuery storage and query costs still exist. So do the PostgreSQL resources and network path needed to read the source. Bruin does not make those disappear. It removes the managed connector's MAR charge and lets you decide where the pipeline runs.
| Option | Software and execution cost | What you are paying for |
|---|---|---|
| Fivetran | About $1,500/month in this 20M-MAR example | Fully managed connector operations and MAR-based usage |
| Bruin CLI + ingestr, run locally or in CI | $0 for the open-source software | Existing machine, CI runner, and warehouse costs |
| Bruin CLI + ingestr on a small server | Usually a small fixed infrastructure bill | The server plus your warehouse costs, with no per-row ingestion fee |
| Bruin Cloud | $0 to less than $100 for a lightweight run profile | Managed execution charged by memory hours, not MAR |
The last row deserves some care. Bruin Cloud includes a default $100 free credit and 10 memory hours. That makes sub-$100 execution plausible for a small batch workload, but you should run a representative week, inspect the memory-hour usage, and extrapolate before promising a monthly number internally. The cost is tied to how the pipeline runs, not to the number of source rows alone.
The obvious answer is cost. It is still not the only one.
When the database gains customers, events, orders, or frequent updates, a MAR-priced connector grows with it. That can be a fair trade when you want a vendor to own the connector, but it also means a simple replication workload becomes more expensive just because your product is doing well.
For a Postgres table with a stable primary key and a sensible updated_at field, the move is often not technically mysterious. You need an incremental load strategy, a destination write strategy, checks, and a cutover plan. That is a proper data-engineering task, but it is not a reason to accept an open-ended per-row bill by default.
Fivetran work often begins in a product UI, even when teams later automate setup. A Bruin migration gives you versioned assets, a reviewable pipeline.yml, SQL or Python transformations next to ingestion, and checks that explain what "healthy" means. It is easier to answer questions such as:
In a Bruin project, you can keep those decisions beside the ingestion asset instead of scattering them across a connector UI, a transformation repo, a scheduler, and a monitoring tool.
The open-source path is useful when private connectivity, VPC deployment, on-prem infrastructure, or a read replica is part of the architecture. You can run Bruin locally, in CI, on a server, or with an existing orchestrator. Bruin Cloud is the managed option when you want schedules, run history, lineage, secure connections, and usage monitoring without operating the server yourself.
Do not replace every Fivetran connector by reflex. A rare SaaS connector with tricky source behaviour may still be worth paying Fivetran for. Start with the high-volume database connector whose behaviour you understand, prove the path, then decide what belongs in the new stack.
The Fivetran-to-Bruin Academy guide is designed for a staged migration, not a one-shot rewrite. It gives an MCP-enabled coding agent a migration prompt and a local skill that imports one selected Fivetran connector with read-only API requests.
Start from a clean directory:
bruin init migration-fivetran fivetran-to-bruin
cd fivetran-to-bruin
The template gives you a migration plan, the coding-agent prompt, and .agents/skills/bruin-fivetran-migrator/. The skill imports a selected connector configuration, writes a redacted capture to .artifacts/, and leaves the decisions in plan.md. Keep the repository-root .bruin.yml and imported artifacts out of Git because that is where your connection configuration and local secrets live.
Bruin MCP lets the agent read current documentation and work with project-aware CLI commands. For Codex, the CLI configuration is:
[mcp_servers.bruin]
command = "bruin"
args = ["mcp"]
The full Bruin MCP setup guide covers other coding agents too. The server command is only bruin mcp; credentials belong in the migration project's local connection configuration, never in an agent chat or MCP config file.
Open a new agent chat from the migration project root and send exactly this:
Read @fivetran-bruin-prompt.md and execute that prompt. The connections are already configured in the root .bruin.yml.
The agent should read plan.md, import one Fivetran connector, and stop for decisions it cannot safely infer. It should not disable Fivetran, enable a production schedule, or write into a production table just because it can see a connector configuration.
For this PostgreSQL-to-BigQuery example, give the agent a concrete scope:
| Decision | Example answer |
|---|---|
| Connector | The single Fivetran PostgreSQL connector ID |
| Source connection | production_postgres |
| Destination connection | analytics_bigquery |
| First target | migration_v0.orders in BigQuery |
| Source table | public.orders |
| Primary key | id |
| Incremental key | updated_at |
| Delete and history behaviour | The agreed behaviour, written down before the run |
For a normal incremental table, the draft will look roughly like this. The final version should use the table name, keys, columns, and destination mapping you approved.
name: migration_v0.orders
type: ingestr
connection: analytics_bigquery
materialization:
type: table
strategy: merge
incremental_key: updated_at
parameters:
source_connection: production_postgres
source_table: public.orders
destination: bigquery
columns:
- name: id
type: integer
primary_key: true
- name: updated_at
type: timestamp
Bruin supports ingestr as a native asset type. Its ingestr asset reference documents the supported destination strategies, connection resolution, schema contracts, and Postgres CDC options. merge needs a primary key, and the incremental key needs to match the source's real change semantics. If updated_at is unreliable, fix that design decision before the migration rather than hoping the tool guesses correctly.
The important part of a Fivetran migration is not writing the first table. It is proving the new table is safe to consume.
Run the initial load into the isolated schema. Then compare:
bruin data-diff --full where the two tables are comparablebruin data-diff compares schemas by default and can add row counts and column statistics with --full. It is useful evidence, not a substitute for the business-level parity checks you agree with the data owner.
Keep Fivetran live while the new path writes to migration_v0. Switch one downstream consumer only after the new output matches or intentionally corrects the old output. Keep a rollback window. Then, and only then, disable the Fivetran connector or redirect consumers to the final Bruin table.
These are not three identical products. Ingestr is the open-source ingestion engine. Bruin uses it natively and adds the broader pipeline workflow. Fivetran is the managed connector service.
| Tool | What it is | Best when | What you need to own |
|---|---|---|---|
| Fivetran | Managed ELT connectors | You want the vendor to operate the connector and the price is acceptable | Connector configuration, usage budget, and downstream pipeline tooling |
| ingestr | Open-source data ingestion CLI | You want fast and cheap data ingestion as a script, job, or CI step | Scheduling, monitoring, transformations, checks, and governance around the load |
| Bruin | Open-source data pipeline CLI with ingestr assets, plus optional managed Cloud | You want ingestion, SQL/Python transforms, quality checks, lineage, and orchestration in one project | The runtime if self-hosted, or a Cloud usage budget if managed |
The practical choice is usually simpler than the product categories make it sound:
For a Postgres-to-BigQuery database connector, the last two are often the cheap Fivetran alternative. Bruin does not replace ingestr in that setup. It gives ingestr a pipeline home.
Yes, for teams that want to migrate a managed connector into an open-source, code-first pipeline. Bruin is broader than ingestion: it uses ingestr for the load, then adds SQL and Python assets, checks, lineage, and orchestration. Validate connector behaviour before you call it a one-for-one substitute for every SaaS source.
The example here models 20 million billable MAR as roughly $1,500 per month. That is not a public rate card calculation. Fivetran charges based on distinct records inserted, updated, or deleted, and pricing varies by plan, contract, connection layout, and usage. Use the current Fivetran pricing estimator for the number that matters to your account.
Yes. Configure a Postgres source connection and a BigQuery destination connection, have the migration flow draft an ingestr asset, then review its primary key, incremental key, write strategy, schema contract, and target before the first load. Start in an isolated destination schema.
No. ingestr is an open-source data ingestion tool. Bruin uses it for native ingestion assets and adds the pipeline layer around it. You can run ingestr by itself for a focused CLI job or use it inside a Bruin project when the load needs transformations, checks, lineage, and managed operations.
Do not replace the production destination immediately. Run Fivetran and Bruin in parallel, write the first Bruin load to an isolated schema, compare output and freshness, switch one consumer at a time, and retain a rollback path. The Academy migration guide walks through the prompt, review gates, and v0 approval flow.
No. The sub-$100 figure is a reasonable budget for a lightweight workload, not a fixed plan price. Bruin Cloud tracks execution by memory hours, so measure a representative run and base your budget on actual usage.
If the only problem is an expensive Postgres connector, start there. Build the parallel path, prove it, and keep the rest of the stack unchanged until there is a reason to move it too. That is how you reduce Fivetran costs without turning a connector migration into a platform rewrite.

What is CDC in data engineering? Learn how change data capture records database changes, differs from ETL and incremental loading, and when to use it.

What is CDC streaming? Learn how it reads database logs, where Kafka fits, how it differs from batch CDC, and when its operational cost is worth it.

A practical comparison of dlt alternatives for data ingestion: Bruin CLI, ingestr, Airbyte, Sling, Meltano, and Fivetran, including a MongoDB to Postgres benchmark.
Practical updates on open-source data pipelines, AI analysts, governance, and what we are shipping at Bruin.