MySQL to Snowflake: The Complete Replication Guide

Intergalactic Data Labs
โ
โ
16 min read
Updated November 9, 2026
To replicate MySQL to Snowflake, you copy each table from one consistent snapshot, then read every insert, update, and delete from the MySQL binary log and MERGE those changes into typed Snowflake tables through a stage and COPY INTO. Twelve tools run this route today. Snowflake Openflow is the native option, Fivetran, Airbyte, Estuary, Hevo, and Stitch are the hosted options, Debezium, Sling, ingestr, and dlt are the build-it-yourself options, and Filament by Galaxy runs the snapshot and binlog change data capture as one process inside your network, with a checksum on every batch.
Approach | Change capture | Deletes | Where it runs | Pricing unit |
|---|---|---|---|---|
Self-hosted CDC | Binlog CDC | Hard delete or flag | Your servers | Free or flat rate |
Snowflake Openflow | Binlog CDC | Soft-delete flag | Snowflake runtime or your AWS VPC | Snowflake credits |
Hosted ELT | Binlog CDC or query polling | Flag or hard delete | Vendor cloud | Rows, GB, credits, or events |
What are the best ETL tools for MySQL to Snowflake?
The best ETL tools for MySQL to Snowflake in 2026 are Filament, Snowflake Openflow, Fivetran, Airbyte, and Estuary. All five read the MySQL binary log, so all five see deletes. They differ in where they run, how they bill, and what they do with a deleted row.
Filament fits teams that want a current replica inside their own network with no row or gigabyte meter. Its
cdc_mergemode removes deleted rows in Snowflake, and each batch carries a CRC32-C checksum the sink recalculates, per the integrity docs.Openflow fits teams that want to stay inside Snowflake. It is generally available and loads through Snowpipe Streaming, per the Openflow MySQL docs.
Fivetran fits teams that will not run any software. It supports MySQL 5.5 through 8.4 and bills on monthly active rows, per its MySQL docs and pricing docs.
Airbyte fits teams that want one open source platform for many sources. Its Snowflake destination writes direct-load typed tables since version 4.0, per the destination docs.
Estuary fits hosted change data capture with optional hard deletes, billed per GB plus per connector, per its pricing docs.
Hevo, Stitch, Debezium, Sling, ingestr, and dlt cover narrower cases, and the fit table further down maps each tool to its job.
How does MySQL to Snowflake replication work?
Every approach does the same two jobs. It copies the tables as they stand, then keeps Snowflake current by reading the changes MySQL writes to its binary log.
The binlog is the change source. In MySQL 8.4 "binary logging is enabled by default, and by default uses the row-based format," per the binary log options page, and row format is what every log-based tool needs. The tool connects as if it were a replica and applies each change downstream. An incremental read on a timestamp column is the alternative, and it never sees a deleted row.
Snowflake loads files, not rows. The fast path is COPY INTO from a stage, then a MERGE that applies the batch by key. Openflow is the exception on this list, since it loads through Snowpipe Streaming into journal tables and merges from there.
Passwords are gone for service users. Snowflake's MFA rollout will "disallow passwords for all service users," with Phase 3 enforced account by account from August to October 2026. Plan on a key pair of at least 2048 bits on a SERVICE user, whichever tool you choose.
How do you stream MySQL changes to Snowflake with binlog change data capture?
Turn on row-based binlog, keep enough of it, and point a log-based tool at the primary with a replication user. The tool snapshots each table, records the binlog position or GTID set, then streams every change after that point into Snowflake.
Keep row format.
binlog_formatdefaults toROWin MySQL 8.4, per the MySQL manual. Statement or mixed format breaks change data capture.Turn on GTID if you can. Filament and Fivetran both use GTIDs when
gtid_modeis on, and Filament's MySQL source docs prefer it "because it survives replica promotion."Size the retention. MySQL keeps binlogs for 30 days by default, but RDS for MySQL keeps none until you set
binlog retention hours, with a maximum of 168, per the RDS docs. Estuary asks for at least 7 days, per its MySQL capture docs.Grant the right privileges. Log readers need
REPLICATION SLAVEandREPLICATION CLIENT, plusSELECTfor the snapshot.Read the writer on Aurora. "Aurora reader instances don't maintain their own binary logs," per the Openflow MySQL docs.
What are the best tools to automatically and continuously sync MySQL to Snowflake?
Openflow and Estuary stream continuously, and Filament, Fivetran, and Airbyte sync on a schedule. Pick the cadence first, because each load wakes a warehouse that bills "per-second billing (with a 60-second minimum each time the warehouse starts)," per the warehouse docs.
Tool | Delivery model | Fastest cadence | Source |
|---|---|---|---|
Filament | Scheduled catch-up runs | As often as you schedule it | |
Openflow | Snowpipe Streaming plus MERGE | Continuous | |
Estuary | Continuous capture, Snowpipe Streaming for delta updates | Continuous | |
Fivetran | Micro-batch | 1 minute on Enterprise and Business Critical | |
Airbyte Cloud | Micro-batch | 5 minutes on Pro, 15 on Plus, 1 hour on Standard | |
Hevo | Micro-batch | 1 hour on the free tier |
Snowpipe Streaming makes rows queryable in "as low as 5 seconds," per the Snowpipe Streaming overview. For most analytics a one to five minute merge is the better trade, because the table holds one current row per key and the warehouse sleeps between loads. Filament fits that pattern. Each run streams from its checkpoint to the current binlog position and exits, so continuous sync is a cron entry or a Kubernetes job.
What are the MySQL to Snowflake replication tools besides Fivetran?
The main alternatives to Fivetran are Filament, Openflow, Airbyte, and Estuary, with Hevo and Stitch as smaller hosted options. Teams usually leave Fivetran over the row meter, since every active row counts once per month toward MAR, with 500,000 MAR on the free plan.
Filament removes the meter. It runs on your own host, merges deletes away, and the only bill is Snowflake warehouse time.
Openflow replaces a third-party vendor with Snowflake itself, billed as Snowflake credits.
Airbyte is open source, with connectors under the Elastic License 2.0, per its license page. Cloud Standard starts at $20 per month with 5 credits and extra credits at $5 each, per its pricing page.
Estuary charges $0.50 per GB plus $100 per month for each of the first six connectors, per its pricing docs.
Hevo and Stitch bill by events, from $299 per month, and by rows, from $100 per month.
Which tools replicate MySQL to Snowflake?
Twelve tools run this route. The table lists how each captures changes, what it does with deletes, where it runs, its license, and its pricing unit.
Tool | Change capture | Deletes | Deployment | License | Pricing unit |
|---|---|---|---|---|---|
Filament | Binlog CDC | Merge removes | Binary, Go library, Helm | Apache 2.0 | None |
Snowflake Openflow | Binlog CDC | Flag | Snowflake runtime or AWS BYOC | Proprietary | Snowflake credits |
Snowflake Connector for MySQL | Binlog CDC | Flag | Native app plus Docker agent | Proprietary | Snowflake credits |
Fivetran | Binlog or Teleport | Flag | Hosted, Hybrid on Enterprise | Proprietary | Monthly active rows |
Airbyte | Binlog via Debezium | Hard delete by default | Cloud or Helm | ELv2 | Credits on Cloud |
Estuary Flow | Binlog CDC | Hard or flag | Hosted, private, BYOC | BSL 1.1 | GB plus per connector |
Debezium plus Kafka connector | Binlog to Kafka | Not reflected | Kafka Connect | Apache 2.0 | Kafka to run |
dlt | Query based | Not from MySQL | Python library | Apache 2.0 | Free, dltHub paid |
Sling | Binlog CDC, paid tier | Hard or flag | CLI | GPL-3.0 | Flat rate token |
ingestr | Binlog CDC | Merge plus flag | CLI | FSL-1.1 | Free |
Hevo | Binlog CDC | Flag | Hosted | Proprietary | Events per month |
Stitch | Log based | Flag | Hosted | Proprietary | Rows per month |
Openflow runs a snapshot, then applies changes with a MERGE keyed on a replication key. Deletes set _SNOWFLAKE_DELETED to true rather than removing the row, and journal tables "are retained indefinitely," per the Openflow MySQL docs. It "supports only username and password authentication with MySQL or MariaDB," and BYOC is AWS only. The older Snowflake Connector for MySQL stays in preview, and general availability "is currently not on our product roadmap."
Fivetran pulls a full dump, then reads the binary log or uses Teleport Sync, which needs only a read-only SQL user but skips tables over 20 million rows, per its MySQL docs. Deletes arrive as a _fivetran_deleted flag, since "we don't delete rows from the destination." Hybrid Deployment needs an Enterprise or Business Critical plan.
Airbyte ships a certified MySQL source that reads the binlog "to incrementally capture deletes in addition to new and updated records." Its Snowflake destination hard deletes by default, with a soft delete option, and deprecated password auth in version 5.0.
Estuary Flow backfills, then reads the binlog, per its MySQL capture docs. Its Snowflake materialization applies changes transactionally, and the Hard Delete option removes deleted rows.
Debezium has no Snowflake sink. Debezium Server 3.7 lists Kafka, Kinesis, JDBC, Iceberg, and others, but not Snowflake. The path runs through Kafka to the Snowflake Connector for Kafka, which lands VARIANT columns and warns that deletes "might not be reflected." You write the MERGE yourself.
dlt, Sling, and ingestr are code-first. dlt's sql_database source documents no MySQL binlog reader. Sling's change capture "requires a CLI Pro Max token or an Advanced Platform Plan," per its docs. ingestr streams the binlog under the mysql+cdc scheme and its LICENSE is the Functional Source License 1.1. AWS DMS is not an option, since its target list has no Snowflake.
Can you sync MariaDB to Snowflake with the same tools?
Yes, with most of them, because MariaDB writes a MySQL-style binary log. Openflow supports MariaDB 11.4 or later, per the Openflow docs. Fivetran has a separate MariaDB connector for 10.1.2 through 11.7, and Estuary has a MariaDB capture for 10.3 and later. Sling and ingestr read the MariaDB binlog too.
Filament's MySQL source targets MySQL 8.0 and later and does not list MariaDB as supported, so test it before relying on it. The best practices carry over. Set binlog_format to ROW, keep at least 7 days of binlog, and connect to the primary or a replica with binary logging on.
How to replicate MySQL to Snowflake with Filament
Filament is an Apache 2.0 replication engine written in Go, built by Galaxy. The MySQL source is marked stable and the Snowflake sink is still in preview. No public benchmark covers this route. On the one route with a public run, Postgres to Postgres, Filament moved 298M rows in 115 s and led every other tool, per the seven-tool benchmark.
What you need. MySQL 8.0 or later with InnoDB tables, a user with REPLICATION SLAVE, REPLICATION CLIENT, SELECT, and LOCK TABLES, and binlog retention that covers the snapshot. The sink page ships the full Snowflake SQL for a role, an X-Small warehouse with AUTO_SUSPEND = 60, a database, and a SERVICE user with key-pair auth. Generate the key with openssl genrsa 2048 piped to pkcs8 -nocrypt.
Define both ends and the pipeline. Connector fields become CLI flags with a source- or sink- prefix, and underscores become hyphens, per the CLI reference. Confirm the auth flag names with filament sink create --help.
What the first run does. For a table with no checkpoint, Filament reads it through a consistent snapshot and the stream "continues from the binlog position captured just before that snapshot opened." Writers of those tables "wait for a couple of round trips and nothing else is blocked." Large tables split into as many as 64 primary-key ranges read in parallel.
How rows land. "Each Arrow batch is encoded as a Snappy-compressed Parquet file in memory," uploaded with PUT to the user's @~ stage, loaded with COPY INTO, and removed. "No external storage integration is required." Merge mode loads each batch into a temporary table and applies one MERGE, so deleted MySQL rows are deleted in Snowflake. Password auth "is not exposed," so the sink uses key pairs or programmatic access tokens.
Keeping it current. Each later run catches up from the saved GTID or file position and exits, and a run with no changes still saves the watermark. Delivery is at-least-once and merge converges by primary key, so a crash mid-transaction replays it safely. A five-minute cron with the auto-suspend above keeps compute idle most of the day.
What breaks in a MySQL to Snowflake pipeline?
The rows rarely fail. The types do.
Trap | MySQL behavior | Snowflake behavior | Fix |
|---|---|---|---|
Zero dates | Stores 0000-00-00 | No such value | Convert to NULL, not the epoch |
TINYINT(1) | Synonym for BOOL | BOOLEAN or NUMBER, tool decides | Choose per column before loading |
DECIMAL over 38 digits | Up to 65 digits | 38 digit maximum | Widen to text or round on purpose |
DATETIME | No time zone stored | TIMESTAMP_NTZ | Set the session zone once |
TIMESTAMP | Stored as UTC, shown in session zone | TIMESTAMP_TZ | Map to a zoned type |
ENUM and SET | Index plus label | TEXT | Expect the label, not the index |
JSON | Native JSON type | VARIANT | Load as VARIANT, not a string |
Zero dates are the loudest failure. MySQL converts invalid dates to the zero value when the SQL mode permits it. Airbyte reads zero dates as NULL in the snapshot but as the Unix epoch in later binlog syncs for TIMESTAMP columns, per its MySQL docs. Decide before the first load, because a rewrite after data lands means a re-snapshot.
Booleans and decimals need a decision. MySQL's BOOL is a synonym for TINYINT(1). Airbyte emits boolean by default while Openflow emits INT. MySQL DECIMAL allows more digits than Snowflake's NUMBER, and Filament writes such columns as TEXT instead of rounding.
Lost logs and schema changes end the run. If the binlog is purged, ingestr says "the run fails instead of taking a partial snapshot," Fivetran requires a re-sync, and Filament re-snapshots the table. A column-count mismatch after DDL fails a Filament run rather than mis-mapping values.
Which tool fits which job?
For a current Snowflake copy of production MySQL that never leaves your network, Filament is the pick, and the table maps the other jobs.
Job | Pick | Why |
|---|---|---|
Replica inside your network, deletes propagated | Filament | Snapshot plus binlog from one point, merge removes deletes, checksummed batches, no meter |
Everything inside Snowflake, no software to run | Openflow | Generally available, native MERGE, billed as Snowflake credits |
Widest catalog, budget by rows | Fivetran | Binlog or Teleport, MAR meter, 500k free |
One open source platform for many sources | Airbyte | Certified MySQL source, hard deletes by default |
Hosted CDC with hard deletes | Estuary Flow | Transactional apply, Hard Delete option, per GB |
Kafka already in production | Debezium plus Kafka connector | The change stream is already there, MERGE is yours |
Filament answers deletes, consistent start, locality, auth, and integrity with documented behavior and runs as one process. A team that lives entirely inside Snowflake should take Openflow, and a team that will not operate software should take a hosted service and set the auto-suspend low.
Related guides in this series cover Postgres to Snowflake, MySQL binlog change data capture, MySQL to Postgres, full load vs incremental vs CDC, the best change data capture tools, and the best Airbyte alternatives.
Frequently asked questions
What are the best ETL tools for MySQL to Snowflake?
Filament, Snowflake Openflow, Fivetran, Airbyte, and Estuary are the main options in 2026, and all five read the MySQL binary log. Filament runs inside your network, merges deletes away, and checksums every batch. Openflow runs inside Snowflake. Fivetran is fully managed and bills monthly active rows. Airbyte is open source with a credit-based cloud. Estuary bills per GB plus per connector.
How do I replicate MySQL to Snowflake?
Snapshot each table, load it into Snowflake through a stage and COPY INTO, then read the MySQL binary log and apply inserts, updates, and deletes with MERGE. Openflow, hosted services like Fivetran and Estuary, and self-hosted tools like Debezium, Sling, ingestr, and Filament all follow this pattern.
How do I automatically keep MySQL and Snowflake in sync?
Use a binlog change data capture tool on a schedule or a stream. Openflow and Estuary capture continuously. Fivetran syncs as often as every minute on Enterprise, Airbyte Cloud every 5 minutes on Pro, and Filament as often as you schedule its catch-up runs. A one to five minute merge keeps one current row per key and lets the warehouse suspend between loads.
What are the MySQL to Snowflake tools besides Fivetran?
Filament, Openflow, Airbyte, and Estuary, with Hevo and Stitch as smaller hosted options. Filament removes the row meter and runs on your own host. Openflow keeps the pipeline inside Snowflake. Airbyte is open source with credits on Cloud. Estuary bills per GB plus per connector.
Does MySQL to Snowflake change data capture handle deletes?
Yes, if the tool reads the binary log. A timestamp-based sync cannot see a hard delete because the row is gone. Fivetran and Openflow flag the row as deleted, Airbyte hard deletes by default, Estuary and Sling can remove or flag it, and Filament's merge mode removes it.
What binlog retention should I set for MySQL to Snowflake?
Long enough to cover the initial snapshot plus any pause in syncing. MySQL's default is 30 days, but RDS for MySQL retains nothing by default and caps retention at 168 hours. Fivetran recommends 7 days, Estuary at least 7, and Airbyte 10. A purged log forces a re-snapshot.
Does the initial snapshot lock my MySQL tables?
Briefly, on most tools. The snapshot and the binlog position must agree, so tools take short table-level locks while the position is captured. In Filament, writers of those tables wait for a couple of round trips and nothing else is blocked.
What MySQL types break when loading into Snowflake?
Zero dates, which Snowflake rejects. TINYINT(1) columns that MySQL treats as booleans. DECIMAL columns beyond 38 digits. DATETIME columns with no time zone. ENUM and SET values, which land as text. JSON, which needs a VARIANT column. Check each before the first load.
Can I sync MariaDB to Snowflake?
Yes. Openflow supports MariaDB 11.4 or later, Fivetran has a MariaDB connector for 10.1.2 through 11.7, Estuary captures MariaDB 10.3 and later, and Sling and ingestr read its binlog. Filament's MySQL source targets MySQL 8.0 and later and does not list MariaDB. Use ROW binlog format and keep at least 7 days of logs.
How do I set up MySQL to Snowflake replication with Filament?
Create a MySQL source with replication set to cdc, a Snowflake sink with key-pair auth, and a pipeline with the merge write mode. The first run snapshots each table, stages Parquet to your user stage, loads it with COPY INTO, and streams the binlog from the position captured before the snapshot. Later runs catch up from the checkpoint.
Does Filament need an S3 bucket to load Snowflake?
No. Its Snowflake sink encodes each batch as Parquet in memory, uploads it with PUT to the user's internal stage, loads it with COPY INTO, and removes the staged object. No bucket, IAM role, or storage integration sits between MySQL and Snowflake.
Is Filament faster than Fivetran or Airbyte for MySQL to Snowflake?
No public benchmark covers this route, so no tool can claim it. On the one route with a public run, Postgres to Postgres, Filament moved 298 million rows in 115 seconds and finished ahead of every other tool measured.
More articles
Questions
Answered
FAQ
What does Galaxy do?
What is Filament?
What is enterprise context management?
What does working with Galaxy look like?
How do you handle security and compliance?
Why does Galaxy build in the open?
Company
Copyright ยฉ 2026 Galaxy. All rights reserved.