FAQ

The honest answers to the questions you're already asking

Straight answers on what Fabric replicates, how it is priced, and what happens when the source, the bill or the pipeline misbehaves — each one linking to the page or doc that goes deeper.

Topic

Product

What is Fabric, and what does it replicate from and to?

Fabric's answer

Fabric is a change data capture (CDC) tool. It reads changes from PostgreSQL, MySQL, MariaDB, SQL Server, IBM Db2, MongoDB and Zoho CRM, and writes them to Apache Iceberg, Delta Lake, PostgreSQL, Snowflake or ClickHouse. It reads each database's change log itself, so there is no Debezium, Kafka, Kafka Connect or schema registry for anyone to run.

Go deeper: Read the introduction

Is Fabric hosted or self-hosted? Does my data leave my network?

Fabric's answer

Hosted, by default. We run the platform and the pipeline runners, and you give us credentials for your source and destination, so rows pass through our runners on their way to your destination. If data can't leave your network, run Fabric yourself: Helm charts for Kubernetes, or Docker Compose on a single machine. A self-hosted install sends us a daily usage report with row counts and run state. It never includes row data, credentials, table names or schemas.

Go deeper: How Fabric is deployed

Do I need Kafka, Kafka Connect or a schema registry?

General answer

With Debezium's standard setup, yes. Debezium runs as Kafka Connect connectors, so you run Kafka, Kafka Connect and usually a schema registry. Some CDC tools hide that behind a managed service; others read the database log without Kafka at all.

How Fabric does it

No. Fabric reads the Postgres WAL (through pgoutput or wal2json) and the MySQL binlog itself, and writes straight to the destination. There is no Kafka, Kafka Connect or schema registry anywhere in the stack, hosted or self-hosted. Each source gets one runner that does both the reading and the writing.

Go deeper: Compare the operations row

Why not just use Debezium?

Fabric's answer

You can. Debezium is solid, and Fabric reads the same Postgres log formats, pgoutput and wal2json. The difference is everything around the decoder. With Debezium you also run Kafka, Kafka Connect and a schema registry, and you still have to build the lakehouse writer and the compaction jobs. Fabric reads the log, writes the tables and maintains them, as one product.

Go deeper: Compare Fabric and Debezium

How does Fabric compare to Debezium, Airbyte and Fivetran?

General answer

Debezium is an open-source CDC engine built on Kafka Connect. Airbyte is an ELT platform that uses Debezium for database CDC. Fivetran is a closed-source managed service. The biggest difference between them is how much you have to run yourself.

How Fabric does it

Our comparison page puts Fabric next to Fivetran, Debezium with Tableflow, Estuary and a do-it-yourself Debezium stack, row by row: operations, credentials, destinations, table maintenance, schema changes, freshness and initial loads. Every cell about another vendor cites that vendor's own docs. The short version for the hosted product: we run the control plane, the runners and the maintenance; you bring the credentials. Self-hosted, you run the same product in your own cluster.

Go deeper: See the full comparison

Does self-hosted Fabric phone home, and with what?

Fabric's answer

Yes, once a day, and the setup screen lists exactly what is sent: the install ID, the Fabric version, rows per day and the first day rows landed, and for each pipeline its name, whether it is running, how long it ran and its row counts. Your data, credentials, table names and schemas are never sent. The report is signed, and it keeps your account's usage cap and credit correct when you run both hosted and self-hosted pipelines.

Go deeper: See the setup disclosure

Topic

Getting started

How much engineering time will this take off my team?

Fabric's answer

Mostly the infrastructure work. With the hosted product, nobody on your team stands up or upgrades Kafka, Kafka Connect or a schema registry, writes compaction and snapshot-expiry jobs, or gets paged when a schema change breaks a pipeline. We run the control plane, the runners and the maintenance. How many hours that frees up depends on what you run today.

Go deeper: See what you stop operating

How hard is it to set up?

Fabric's answer

On the hosted product there is nothing to install. You add a source and a destination, and the pipeline starts. Fabric works with the databases you already run, including managed ones like RDS, Aurora, Cloud SQL and Atlas, and there is no broker to size or connector framework to configure. Self-hosted, you install the Helm charts in your Kubernetes cluster, or use Docker Compose on one machine.

Go deeper: Read the quickstart

What does ongoing maintenance look like?

Fabric's answer

On the hosted product, we handle it: compaction, snapshot expiry, orphan-file cleanup and upgrades. Self-hosted, the same table maintenance is built in and runs on a schedule, so there is no job for you to write. Upgrading means upgrading Fabric itself, not Kafka, Kafka Connect and a schema registry, each on its own release cycle.

Go deeper: How maintenance runs

Topic

Pricing

How much does Fabric cost?

Fabric's answer

Fabric costs $100 a month for each running pipeline, pro-rated by billable days, plus a charge for changed rows. Changed rows are pooled across your account and priced on a curve: $50 per million up to 1M rows a month, falling smoothly to $1 per million from 1B. Initial loads are a flat $1 per million rows. New accounts get a one-time $100 usage credit for 60 days; it covers usage, not the pipeline fee. Free is one pipeline under 1M changed rows a month.

Go deeper: Open the pricing calculator

Will my bill spike after a re-sync or a backfill?

General answer

It depends on how the tool counts rows. Fivetran bills monthly active rows, so a full re-sync can show up on the invoice. Before you choose a tool, check how it prices a reload.

How Fabric does it

Not for re-syncs Fabric causes. When Fabric has to re-snapshot (after an operator reset, a lost replication slot or a forced restart), those rows are free and don't touch your credit or the Free cap. A load you ask for, such as a new table or a re-sync you start, is priced at the flat initial-load rate of $1 per million rows. Your $100 credit pays for it first, and it never counts toward the changed-row curve.

Go deeper: See how usage is metered

Am I billed for a pipeline that is stopped or paused?

Fabric's answer

No. The pipeline fee is pro-rated by billable days, so a pipeline that was stopped or paused for the whole month pays no fee. Rows it moved while it was running still count toward that month's volume. One thing to watch on Postgres: a paused pipeline keeps its replication slot, so your source keeps holding WAL for it. The pipeline's health page shows how much.

Go deeper: Read the billing rules

Topic

Connectors

Which sources and destinations are supported?

Fabric's answer

Sources: PostgreSQL, MySQL, MariaDB, SQL Server, IBM Db2, MongoDB and Zoho CRM. Destinations: Apache Iceberg (including AWS S3 Tables), Delta Lake, PostgreSQL, Snowflake and ClickHouse. Managed versions such as RDS, Aurora, Cloud SQL and Atlas work too. Salesforce, HubSpot, Stripe, Oracle, BigQuery and pgvector are on the roadmap but not shipped. Every connector is built on one internal read/write contract, which is why new ones ship quickly; it is not a plug-in SDK for customers.

Go deeper: See every source and sink

You ship 24 connectors today. Airbyte has 300.

Fabric's answer

Fair. If you need a long list of SaaS sources, Airbyte has them and we don't. Fabric reads from PostgreSQL, MySQL, MariaDB, SQL Server, IBM Db2, MongoDB and Zoho CRM, and writes to Iceberg, Delta Lake, PostgreSQL, Snowflake and ClickHouse. Every connector is built on one internal read/write contract, so new ones ship quickly. Salesforce, HubSpot, Stripe and Oracle are on the roadmap.

Go deeper: See the shipped inventory

What happens if the MySQL binlog is purged while the pipeline is down?

General answer

Set binlog_expire_logs_seconds well above your longest likely outage. Once the binlog position a CDC tool saved has been purged, no tool can resume from it, and you have to re-snapshot the affected tables.

How Fabric does it

The pipeline stops and tells you, instead of quietly starting from now and skipping the gap. Before a pipeline starts, Fabric checks that binlog retention is longer than 72 hours. When it resumes, it checks that the binlog file it saved still exists on the server. If the file is gone, the pipeline fails with "the bookmark was purged; re-snapshot or reset the cursor".

Go deeper: MySQL setup and retention

What happens when a MySQL table's schema changes?

General answer

Some CDC tools read MySQL rows by column position, so a column change can shift values into the wrong columns. Pause CDC around destructive migrations, and re-snapshot the table afterwards if you're not sure.

How Fabric does it

While the pipeline runs, a new column is picked up and added to the destination without a restart. A change made while the pipeline was down is different. MySQL logs rows by position, so a moved column would put values in the wrong place. Fabric compares each table's columns at startup and refuses to resume if they changed, listing what was added, dropped or changed. You then re-snapshot or reset the table. Postgres and SQL Server decode by column name, so they warn and carry on.

Go deeper: Read the schema-evolution rules

Iceberg, Delta Lake or S3 Tables: which should I pick?

General answer

Pick the format your query engines read best and your team can run. Iceberg has the widest engine support, Delta suits teams built around Databricks, and AWS S3 Tables gives up some control in return for maintenance AWS runs for you.

How Fabric does it

Fabric writes all three. Iceberg works with JDBC, REST (Nessie, for example), Glue, Hive and S3 Tables catalogs. Delta Lake needs no catalog. For S3 Tables you give the table bucket ARN, and AWS handles file layout, compaction and credentials, so there is no warehouse path or S3 key to set. We haven't benchmarked which format performs best for a given workload.

Go deeper: Compare the destination writers

How do I replicate hundreds of tables without writing connector config?

General answer

Use a tool that discovers tables from the database catalog and lets you pick them, rather than one where you write connector config by hand.

How Fabric does it

You pick the tables in the UI. Fabric reads the source's catalog, lists every table with its columns, and builds the pipeline from what you select. There is no connector JSON to write at any point, and one runner replicates every table you picked. On MySQL, a table without a primary key is rejected up front, by name and with the fix, rather than failing halfway through a snapshot.

Go deeper: How table selection works

What happens when a column is added, retyped or renamed on the source?

General answer

In CDC a rename looks like a drop plus an add, because the log has no rename event. Added columns usually flow through fine, and type changes are the risky case, so plan drops and retypes with whoever owns the pipeline.

How Fabric does it

Added columns land without a restart, and the destination gets the new column as nullable. Type changes are never applied silently: Fabric logs that the source type changed, then casts each value to the existing type or quarantines it if it can't. A rename shows up as a drop plus an add, so the old column keeps its history and the new one is null for earlier rows. On MySQL, a change made while the pipeline was down needs a re-snapshot.

Go deeper: Read the schema-evolution rules

Topic

Pipeline

How fresh is the data? What's the end-to-end latency?

Fabric's answer

Usually tens of seconds behind the source. Fabric commits to the destination every 30 seconds by default. Postgres changes stream continuously and SQL Server is polled every second, so most of the wait is the commit interval. The UI shows lag in bytes and the age of the last commit. We don't publish p50 or p95 end-to-end latency figures.

Go deeper: See the freshness row

Why is my Postgres WAL growing on an idle or low-traffic database?

General answer

A logical replication slot holds WAL until its consumer confirms it. On a quiet database nothing commits, so nothing gets confirmed and WAL piles up. The usual fixes are a heartbeat that writes and confirms on a schedule, and dropping slots nobody uses.

How Fabric does it

Fabric runs a heartbeat by default. Every 30 seconds it writes one row per pipeline to public.heartbeat on your source, then confirms the position it has safely written to the destination. That moves the slot forward on an idle database, so Postgres can recycle WAL. The heartbeat only confirms what has been durably saved and uses lock and statement timeouts. If it fails, the failure is counted on the pipeline's health page and streaming carries on.

Go deeper: Read the WAL-growth post

What happens to the replication slot when I pause or delete a pipeline?

General answer

An unused logical slot keeps holding WAL until the source runs out of disk. Drop slots you no longer need with pg_drop_replication_slot, and watch pg_replication_slots for retained WAL.

How Fabric does it

Pausing keeps the slot, so the pipeline can pick up where it stopped. The cost is that Postgres keeps WAL for it; the pipeline's health page shows how much and warns past 1 GiB. Deleting a pipeline cleans up everything: it stops the runner, drops the destination tables, drops the slot and clears the saved state. Resetting a single table also starts it cleanly. Fabric doesn't leave orphaned slots behind.

Go deeper: Read the replication lifecycle

Do I need REPLICA IDENTITY FULL? What happens to unchanged TOAST columns?

General answer

Without REPLICA IDENTITY FULL, Postgres logs only the key of the old row on UPDATE and DELETE, and a large TOASTed column the UPDATE didn't change isn't sent at all. Set FULL on tables whose consumers need the whole row.

How Fabric does it

You don't need it, but it's recommended for tables with large text, jsonb or bytea columns. With REPLICA IDENTITY FULL, Fabric takes an unchanged TOAST value from the logged old row. Without it, Fabric reads the missing columns back from the source by key, once per table per commit, so rows still land complete. That value is the one at commit time, which can be newer than the event. The Postgres destination keeps its stored value. No extra columns are added.

Go deeper: Large columns and REPLICA IDENTITY

Can I replicate tables without a primary key?

General answer

A CDC tool needs some way to identify a row for updates and deletes. Without a primary key, you give it a unique key, set a replica identity, or accept append-only data.

How Fabric does it

On Postgres, yes. Fabric warns at setup when a table has no usable replica identity, and you choose the columns that identify a row. The Postgres destination updates and deletes on those columns, and rows with nulls in them go to quarantine. Iceberg, Delta and Snowflake keep an append-only change history, and ClickHouse orders by your chosen columns, or by event time if you set none. On MySQL, no: tables without a primary key are rejected up front, by name.

Go deeper: Source setup and table keys

Why does CDC create thousands of small files in Iceberg, and how do I fix it?

General answer

CDC commits often, and every commit writes new Parquet files, so the table ends up as thousands of tiny files. Commit less often, and run compaction and snapshot expiry regularly, yourself or through a tool that schedules them.

How Fabric does it

Fabric handles both ends. It buffers changes and commits every 30 seconds by default, not on every row. Built-in maintenance then runs on a schedule for each source: it merges small files into larger ones, expires snapshots older than the retention you set, and removes orphaned files. There is no separate job to write or schedule.

Go deeper: How maintenance runs

How are updates, deletes and duplicates applied in the destination? Can events arrive out of order?

General answer

Assume events can arrive more than once. Keep a per-row source position, or use merge-on-read, so readers can remove duplicates, and don't rely on events arriving in commit order.

How Fabric does it

It depends on the destination. Iceberg, Delta, Snowflake and ClickHouse keep a full change history: every insert, update or delete adds a row with the operation, a deleted flag, the source position and the source timestamp. You get the current state by keeping the latest row per key. The Postgres destination upserts and deletes for real. The source position sorts in commit order, and snapshot rows sort before streamed ones, so one window function removes duplicates even when events arrive out of order.

Go deeper: Read the landing columns

How do I add a new table to a running pipeline? Is it backfilled?

General answer

With Debezium you edit the connector config and usually trigger a snapshot of the new table yourself. Ideally the tool notices the new table, snapshots it, and keeps streaming the others without a pause.

How Fabric does it

Add it to the source's table selection while the pipeline runs. Fabric snapshots only the new table, then streams it from the point where the snapshot began, so nothing is missed or duplicated. The other tables aren't touched. If you add a table while another is still being snapshotted, Fabric folds both into one snapshot pass instead of running two at once.

Go deeper: Add a table mid-pipeline

What happens to bad data, like a blank string in a UUID column?

General answer

A value that can't be converted should go to a quarantine with the reason and the original row, rather than crashing the pipeline or quietly turning into null. Fix the mapping, then replay the stored rows.

How Fabric does it

That row goes to quarantine and the pipeline keeps running. Fabric checks every value against its column type as it lands. A blank string in a UUID column is rejected as invalid_uuid, and the row is stored with the column, the reason and its original values, kept for review and replay. The rest of the batch commits normally, and the quarantine count shows on the pipeline's health page. Replay is manual today; there is no replay button or API.

Go deeper: Read the full story

What happens if the pipeline crashes mid-batch? Will I lose or duplicate rows?

General answer

With at-least-once CDC, a crash means the last uncommitted batch gets written again. Make the destination idempotent, with upserts, insert tokens or deduplication on the source position, and the repeats go away.

How Fabric does it

You won't lose rows, and repeats are removed. Fabric saves its resume point in the same transaction that records the destination commit, so after a crash the next run rewrites only the uncommitted batch. MySQL skips rows it has already passed, Snowflake and ClickHouse ignore a batch they have already received, and the lakehouse tables can be deduplicated on the source position. Fabric also refuses to move a resume point backwards.

Go deeper: How checkpoints survive a crash

Does the initial snapshot of a very large table block streaming? Can it resume if it fails partway?

General answer

A long snapshot can outlast your log retention, so the tool should record the log position before it starts scanning and stream from there afterwards. It should also resume a failed snapshot from where it stopped, not from the beginning.

How Fabric does it

Streaming waits for the snapshot, but no changes are lost, and yes, it resumes. Fabric records the log position (binlog position, WAL LSN or SQL Server LSN) before it reads the first row, scans the table, then streams everything after that position. The scan runs in chunks and saves its progress per table, so a failed or killed snapshot picks up from the last key it read.

Go deeper: How snapshots and streaming share a runner

Is Fabric's delivery exactly-once or at-least-once?

General answer

Log-based CDC is at-least-once by nature. Tools that promise exactly-once get there with idempotent writes, so ask which mechanism applies to your destination.

How Fabric does it

At-least-once, with duplicates removed for each destination. The resume point is saved together with the destination commit, so after a crash only the last uncommitted batch is written again. MySQL skips rows it has already passed, Snowflake and ClickHouse ignore repeated batches, and in the lakehouse tables you deduplicate on the source position column, which sorts in commit order.

Go deeper: Read about source offsets and dedupe

Topic

Observability

How do I see replication lag, and get alerted on it?

General answer

For Postgres, watch retained WAL in pg_replication_slots and lag in pg_stat_replication, and alert from your own monitoring. Most CDC tools show lag but don't page you.

How Fabric does it

Lag is on the pipeline page, sampled at every commit: bytes behind the source, how much WAL the slot is holding, the slot's wal_status and any run of heartbeat failures. Old samples are marked as stale rather than shown as current. Alerting is the gap: Fabric shows lag but does not send email or webhook alerts. If a runner stalls for more than 15 minutes, Fabric restarts it.

Go deeper: What the health page shows

How do I monitor throughput, errors and quarantined rows?

General answer

Whatever tool you use, alert on three things: lag behind the source log, the age of the last successful commit, and any error or quarantine count above zero. Each one points to a different kind of failure.

How Fabric does it

Each pipeline has a health page with commit activity, snapshot progress per table, the age of the last commit (flagged as stalled when it gets old) and the number of quarantined rows. The API adds per-table commit metrics with an hourly history, and daily usage. When a runner crashes, Fabric tells you whether it stopped cleanly or was killed mid-shutdown, and what it will replay.

Go deeper: Read the monitoring guide

Topic

Security

Is it secure? What about the DPA, encryption and access?

Fabric's answer

Source credentials are encrypted before they're stored and can't be read back in the UI. Each hosted workspace gets its own Kubernetes namespace with resource quotas, network traffic denied by default, and a database role limited by row-level security. Runners accept no inbound connections. The hosted service requires TLS to your database by default; self-hosted, you choose the TLS mode per source. Backups, hosting, vulnerability response and the DPA are policy and legal commitments, not something the code can show.

Go deeper: How the hosted service is isolated

Get started

Streaming by end of day.

Sign up, point Fabric at your operational database, and pick where the tables land. No Kafka, no schema registry, no pipeline team to staff.

Product updates only, no spam.