Skip to content
adapters.io

MySQL to Snowflake migration tools, connectors, replication and data type mapping compared, including the binlog setting Azure will not let you change

Twelve tools that move a MySQL database into Snowflake, and the two things no feature list covers. Snowflake's first-party connector needs binlog_row_metadata set to full, and Snowflake itself notes that on Azure Database for MySQL that variable is not user modifiable without a Microsoft support ticket. And Snowflake's own connector family does not answer the same overflow the same way twice. Everything here was checked against the MySQL 8.4 Reference Manual on 6 September 2026.

Try the live demo

No credit card required.

Field mapping auto-plugged · tap a port to rewire

5 sample records ready

Vendor documentation read 6 September 2026 · Last updated September 2026

Which MySQL to Snowflake migration tool should you use?

Start with Snowflake Openflow if your source qualifies, because it is first-party, it reads the binary log, and it gives you the backfill and the ongoing sync from one mechanism. Two things disqualify it and neither is a feature comparison: it requires MySQL 8 or later, and it requires binlog_row_metadata set to full, which Snowflake states is "not user modifiable" on Azure Database for MySQL and needs a Microsoft support ticket. If you are on MySQL 5.7 or on Azure, look at AWS DMS, Fivetran, Debezium or a plain export instead. Whichever you pick, decide what your TINYINT(1) columns mean before the first load, because MySQL and Snowflake disagree about whether the value 2 is true.

One scoping note before anything else. If this is a genuine one-time lift with no ongoing sync, the cheapest correct answer on this page is mysqldump plus COPY INTO, and no vendor will tell you that. For the wider category see data migration tools, and for the continuous load rather than the one time move, Snowflake ETL tools.

Snowflake's own connectors do not answer the same question twice

Snowflake publishes a data mapping page for its MySQL connector and another for its SQL Server connector. Both are the same product family, both describe how a source column becomes a Snowflake column, and they handle a decimal overflow and a boolean in different ways without either page acknowledging the other. Alongside that sit three prerequisites in the setup page that decide whether the connector can run at all. We read all of it against the MySQL 8.4 Reference Manual on 6 September 2026. The last column is what we would ship.

What is at stake What Snowflake's docs say What the primary source says What we would ship
DECIMAL above 38 digits The Openflow MySQL connector says the MySQL maximum is 65 digits, the Snowflake maximum is 38, and "precision is lost when exceeded". The Openflow SQL Server connector, same product family, says that when precision exceeds 38 "the value is stored as TEXT". MySQL documents a maximum of 65 digits for DECIMAL with up to 30 after the point. Snowflake caps NUMBER at 38 digits of precision and 37 of scale. So one Snowflake connector answers an overflow by quietly returning a shorter number that still adds up, and another answers it by changing the column to a string that breaks every aggregate. One vendor, one condition, two opposite behaviors, and neither page mentions the other. Measure the real magnitude, then declare NUMBER(38,s) by hand
BOOL and TINYINT(1) Openflow maps TINYINT and BOOL to INT. The SQL Server connector maps that database's BIT to a real Snowflake BOOLEAN. MySQL states BOOL and BOOLEAN are synonyms for TINYINT(1), that zero is false and non-zero is true, but that the constants TRUE and FALSE are aliases for exactly 1 and 0, so 2 = TRUE evaluates to false. Snowflake converts any non-zero number to TRUE. A column holding 2 is therefore excluded by a = TRUE filter in MySQL and included by the same filter in Snowflake. Same predicate, different row count, no error either side. Decide what every non-zero non-one value means, then cast explicitly
BIT(1) flag columns Openflow maps MySQL BIT to TEXT and states it is "represented as a hexadecimal string". The same vendor's SQL Server connector maps BIT straight to BOOLEAN. MySQL BIT(M) stores 1 to 64 bits and defaults to 1 bit, which is how a large share of MySQL schemas spell a yes or no flag. Arriving as hex text means every WHERE clause over that flag is now a string comparison, it cannot be indexed as a boolean, and a MySQL schema and a SQL Server schema describing the same business flag land in Snowflake as two different types from one vendor's connector suite. Cast to BOOLEAN in the target DDL rather than filtering on the hex
DATETIME against TIMESTAMP Openflow maps DATETIME to TIMESTAMP_NTZ and TIMESTAMP to TIMESTAMP_TZ, noting that TIMESTAMP values "are stored in UTC". This one is correct and worth saying so. MySQL documents that it "converts TIMESTAMP values from the current time zone to UTC for storage, and back from UTC to the current time zone for retrieval. (This does not occur for other types such as DATETIME.)" The trap is upstream of Snowflake: two MySQL types that look interchangeable to an application developer produce two different Snowflake types with different time zone behavior, and MySQL TIMESTAMP stops at 2038-01-19 while DATETIME runs to the year 9999. Standardize on one type per table before the migration, not after
binlog_row_metadata on Azure Snowflake requires binlog_row_metadata set to full, because that is what carries column names and primary key information. In the same page it notes that on Azure Database for MySQL this variable is "not user modifiable" and needs a Microsoft support ticket. This is the prerequisite that decides the project and it is a line of small print rather than a heading. The free first-party connector cannot be switched on against an Azure-hosted MySQL instance until another vendor changes a setting for you, on their timetable. It is not a licensing cost like the Oracle route carries, but it is the same shape of problem: the free option depends on somebody else's product. Open the Microsoft ticket during scoping, or plan for a query-based tool
Binlog retention Snowflake recommends binlog_expire_logs_seconds of at least 259200, which is 72 hours, so a paused pipeline can be repaired. Its own Amazon RDS instruction demonstrates the change with mysql.rds_set_configuration setting binlog retention hours to 24. Twenty-four hours is a third of the retention the same page recommends. Copy the RDS example verbatim, as most people copying a documented command will, and a pipeline that breaks on a Friday evening has lost its position in the log before anybody looks at it on Monday. The recovery is then a full re-snapshot of the source rather than a resume. Set 72 hours on RDS too, and alert on replication lag rather than on failure
MySQL 5.7 and MariaDB The connector requires MySQL 8 or later. MariaDB is supported through the MariaDB JDBC driver, with binlog_legacy_event_pos set to ON. MySQL 5.7 is still in production across a great many US mid-market applications, and for those the first-party option does not exist at any price until the database is upgraded. The MariaDB support is the opposite story and is worth knowing, because almost no comparison of this route mentions that Snowflake's connector covers MariaDB at all, and teams assume they need a third-party tool. Confirm the version and fork first, before any feature comparison
SET, ENUM and everything unlisted ENUM becomes TEXT. SET becomes TEXT "stored as a comma-separated string in column declaration order". Openflow is explicit that any MySQL type not in its table is mapped to TEXT by default. MySQL stores SET as a bitmask, so declaration order is a property of the DDL rather than of the data, and any code that read the set as a set now parses a string whose order depends on how the column was declared years ago. The catch-all matters more: MySQL spatial types such as GEOMETRY, POINT and POLYGON appear nowhere in the mapping table, so they take the TEXT default with no warning at any point. Inventory information_schema.columns for every type outside the table

None of this makes the documentation useless and we would still start with it. It makes the point that a published mapping is a starting position rather than a fact, even when the vendor publishing it owns the destination. The second row is the one to act on today, because TINYINT(1) is how MySQL spells a boolean and it is the row where a correct load produces a different answer. The statement level version, with a query that proves each risky column before you load it, is in convert MySQL data types to Snowflake.

MySQL to Snowflake migration tools and connectors compared

Pricing models rather than price tags, because every vendor here except us either quotes or meters, and any figure printed on this page would be stale within a quarter. Snowflake publishes no list price for Openflow beyond the credit model, so this page says that instead of inventing one. Where a tool is wrong for a job, the last column says so.

Tool Approach Best for Billing unit Where it costs you
Snowflake Openflow First-party managed connector reading the MySQL binary log Teams on MySQL 8 or later, already committed to Snowflake Snowflake credits, metered as warehouse and service time Requires MySQL 8 or later, plus four binlog settings including binlog_row_metadata set to full, which Azure Database for MySQL will not let you change without a Microsoft support ticket.
AWS DMS Managed replication with MySQL CDC read from the binary log MySQL already inside AWS on RDS, Aurora or EC2 Metered by replication instance hour plus storage The instance bills whether or not data is flowing, and its own type conversion defaults are a third mapping to audit rather than a tie-breaker between the two Snowflake publishes.
Fivetran Fully managed ELT with schema drift handling Teams who want zero pipeline maintenance and have predictable volume Monthly active rows A migration backfill is the largest active-row month you will ever have, and every reload while you correct the mapping bills again at that scale.
Debezium Open source MySQL binlog reader publishing to Kafka Teams already running Kafka who want to own the capture layer Free, plus whatever Kafka costs you to operate It captures changes and does not deliver to Snowflake, so you build and operate the sink, the schema handling and the merge logic yourself. The capture is the easy half.
Airbyte Open source connector framework, self-hosted or cloud Engineering teams who prefer to own and patch the pipeline Free self-hosted, capacity-based in cloud Self-hosting moves the cost from a license to your on-call rota, and a binlog consumer that falls behind its retention window fails in a way that needs a full re-snapshot.
Estuary Flow Streaming CDC with a persistent change log between source and target Low latency requirements without operating Kafka yourself By data volume and connector You are buying a streaming platform. If the requirement is a nightly warehouse load, a large part of what you are paying for will never be switched on.
Striim Streaming CDC with in-flight transformation Sub-minute latency across many schemas at once By capacity and connector Enterprise shape and enterprise sales cycle. Overpowered for a single MySQL schema, and no public price, so budgeting is a conversation rather than a calculation.
Qlik Replicate Log based CDC with a long history of relational sources Large regulated estates that want a specialist rather than a generalist Quoted, enterprise agreement Priced and sold as enterprise software, so it is the wrong shape for one database. No public price, which makes early budgeting guesswork.
Matillion Load plus in-warehouse transformation Teams who want the modelling layer and the pipeline from one vendor Credit-based consumption The transformation layer is the product. If you only need MySQL rows in Snowflake you are paying for a great deal you will not use.
Hevo Data Managed no-code pipelines with in-flight transformation Smaller teams wanting a managed pipeline without enterprise pricing By events loaded per month Event metering behaves like row metering during a backfill, which is exactly the moment your volume spikes and your mapping is still wrong.
mysqldump plus COPY INTO Export to files, stage them, bulk load with COPY INTO A genuine one-time lift with no ongoing sync requirement Free, beyond the Snowflake warehouse time to load Cheapest option on this page by a wide margin and the right answer more often than vendors admit. It gives you no change capture at all, so it stops working the day the two systems must agree tomorrow as well.
Adapters Field-level mapping you set once, then scheduled incremental sync Teams who want the mapping explicit and the bill flat Flat $49 a month, not metered by rows We are not the right tool for a pure one-time bulk lift of a decade of history, we do not do sub-second streaming, and we do not do in-warehouse modelling.

MySQL to Snowflake data type mapping, and what each one costs

Every mapping Snowflake publishes for this route, with the consequence rather than just the target type. The third column is the part no vendor documentation includes, because a mapping that works is not the same as a mapping that means what it used to mean.

MySQL column Snowflake target What it costs you
DECIMAL(M,D), NUMERIC NUMBER Clean to 38 digits. MySQL allows 65 with up to 30 after the point, and past 38 Snowflake's MySQL connector documents that precision is lost rather than that the load fails.
TINYINT, BOOL, BOOLEAN INT Your booleans arrive as numbers. MySQL says non-zero is true but that TRUE is literally 1, while Snowflake treats every non-zero value as true, so a column holding 2 changes sides.
SMALLINT, MEDIUMINT, INT INT Clean. Snowflake INT is NUMBER(38,0), so every MySQL integer width fits with room to spare and the narrowing risk runs the other way.
BIGINT INT Clean, including BIGINT UNSIGNED. Its maximum is twenty digits against Snowflake's thirty-eight. MySQL itself warns that its own arithmetic on unsigned values above 63 bits can round.
YEAR INT Becomes an ordinary number. The two-digit input rules and the 1901 to 2155 range MySQL enforced for you are no longer enforced by anything.
BIT(M) TEXT A hexadecimal string. BIT(1) is a common way to spell a flag in MySQL, and every filter over it becomes a string comparison unless you cast in the target DDL.
FLOAT, DOUBLE FLOAT Both widen to 64 bit, since Snowflake stores all floating point that way. Snowflake documents roughly 15 digits of precision and warns about rounding, so keep money out of these.
DATE DATE Clean, with one caveat MySQL brings: zero dates such as 0000-00-00 are legal in some MySQL modes and have no representation in Snowflake at all.
DATETIME TIMESTAMP_NTZ Correct, and the right choice. MySQL performs no time zone conversion on DATETIME, so no time zone in the target is the honest mapping. Range runs to the year 9999.
TIMESTAMP TIMESTAMP_TZ Also correct, and different from the row above for good reason. MySQL stores TIMESTAMP in UTC and converts on read. Remember it stops at 2038-01-19, which the target type does not.
TIME TIME Clean for a clock time. MySQL TIME also legally holds a duration from -838 to 838 hours, which is not a clock time and does not survive.
CHAR(n) TEXT Snowflake documents that trailing spaces are not preserved. If any application compared or hashed the padded value, that comparison now behaves differently.
VARCHAR(n) TEXT Clean, and the declared length disappears. Snowflake TEXT is unbounded to 16 MB, so a length constraint the database used to enforce becomes an application concern.
TINYTEXT, TEXT, MEDIUMTEXT TEXT Clean. All three land in the same target type, so a distinction MySQL made about storage stops carrying any meaning downstream.
LONGTEXT TEXT Supported to 16 MB by default against a MySQL ceiling of 4 GB. The limit is raisable and is not raised for you, and the rows that hit it are your largest documents.
ENUM TEXT The allowed value list is gone. MySQL rejected an out-of-range value at write time; nothing in Snowflake will, so the constraint has to move into the pipeline or a check.
SET TEXT A comma-separated string in column declaration order. MySQL stored a bitmask, so anything that treated it as a set now parses a string whose order comes from old DDL.
BINARY, VARBINARY BINARY Clean. Fixed-length BINARY padding behaves as MySQL stored it rather than as the type promised, so compare on length as well as content.
TINYBLOB, BLOB BINARY Clean at these sizes. Both sit comfortably inside the connector default.
MEDIUMBLOB, LONGBLOB BINARY Default ceiling of 8 MB against a LONGBLOB maximum of 4 GB. Sharper than the text case, because nobody eyeballs binary payloads after a load.
JSON VARIANT The one place Snowflake is genuinely better. Note the setup constraint: binlog_row_value_options must be empty, so partial JSON updates cannot be used at all.
GEOMETRY, POINT, POLYGON TEXT Not in the mapping table at all, so they take the unlisted default and arrive as strings. Every spatial function you were using stops existing.
Anything else TEXT Snowflake states any unlisted MySQL type is mapped to TEXT by default. Nothing fails, and the problem surfaces months later in a report that cannot aggregate a column everyone assumed was structured.

Eight ways this migration fails while reporting success

None of these raise an error. Each one leaves a green pipeline, a reconciled row count and a number somewhere downstream that is quietly wrong. They are the reason value-level reconciliation is worth more than any dashboard the tool gives you.

Failure What you see What it actually costs
A number that quietly got shorter A wide DECIMAL loads without complaint and every row count reconciles. Snowflake's MySQL connector documents that MySQL reaches 65 digits, Snowflake 38, and "precision is lost when exceeded". The value still looks like a number and still sums, so no aggregate errors and no cast is needed to hide it. The neighboring SQL Server connector answers the same condition by storing TEXT, which at least breaks loudly.
A boolean filter that changed its mind The same WHERE clause returns a different row count in Snowflake than in MySQL. MySQL BOOL is TINYINT(1) and holds any small integer. MySQL evaluates 2 = TRUE as false, because TRUE is an alias for 1. Snowflake converts every non-zero number to TRUE. Openflow maps the column to INT and preserves the value, so the data is right and the answer is different.
A flag that became a hex string A BIT(1) column arrives populated and every query over it returns nothing. Openflow represents BIT as a hexadecimal string. Filters written as a boolean comparison silently match no rows rather than erroring, which reads in a dashboard as a metric that fell to zero rather than as a broken pipeline.
A spatial column nobody mapped A GEOMETRY or POINT column loads and looks populated. MySQL spatial types appear nowhere in the published mapping table, so they take the documented TEXT default. No warning is raised at any point. The neighboring SQL Server connector is at least explicit that its spatial values "are inserted as NULL", so the same vendor fails two ways on one concept.
A pipeline that cannot resume The connector is paused for a weekend and then will not restart from where it stopped. Snowflake recommends binlog_expire_logs_seconds of at least 259200 seconds, or 72 hours, and its own RDS example sets 24. Once the position falls off the end of the retained log there is no resume, only a fresh snapshot of the whole source, at full backfill cost.
A connector that will not start on Azure Every setting looks right and the connector still refuses the source. binlog_row_metadata must be full and Azure Database for MySQL does not let you change it. Snowflake states it is "not user modifiable" there and points at a Microsoft support ticket. This is a scoping question, not a debugging question, and it is worth an hour before the project is committed rather than a week after.
Constraints accepted and ignored Your primary keys and foreign keys are created in Snowflake without complaint. Snowflake does not enforce PRIMARY KEY, UNIQUE or FOREIGN KEY on standard tables. Only NOT NULL and CHECK are always enforced. Coming from MySQL with InnoDB foreign keys switched on, this is a larger change than it sounds, and duplicate keys appear first as double-counted revenue.
A JSON option that blocks the load JSON columns are configured for partial updates and the connector rejects the configuration. Snowflake requires binlog_row_value_options to be left empty, because it cannot consume partial JSON updates. On a MySQL 8 instance tuned for JSON-heavy write throughput, that setting is often deliberately on, and turning it off is a source-side performance decision rather than a pipeline checkbox.

Six numbers that decide this migration

Every figure below was read from primary vendor documentation on 6 September 2026 and is sourced under the card. Where a vendor publishes no number, this page says so rather than inventing one.

65 against 38

Maximum DECIMAL digits in MySQL against the Snowflake maximum. Snowflake's MySQL connector answers the overflow with lost precision; its SQL Server connector answers the same overflow by storing TEXT.

MySQL 8.4 Reference Manual, Snowflake numeric data types, and both Openflow connector data mapping pages, read 6 September 2026

MySQL 8

The oldest version Snowflake's connector supports. A MySQL 5.7 instance cannot use the first-party option at any price until it is upgraded. MariaDB is supported, with binlog_legacy_event_pos set to ON.

Openflow Connector for MySQL setup, read 6 September 2026

Not user modifiable

Snowflake's own description of binlog_row_metadata on Azure Database for MySQL, a setting its connector requires. Changing it needs a Microsoft support ticket.

Openflow Connector for MySQL setup, read 6 September 2026

259200 against 24

Recommended binlog retention in seconds, which is 72 hours, against the 24 hours shown in the same page's Amazon RDS example. Copy the example and you keep a third of the recommended window.

Openflow Connector for MySQL setup, read 6 September 2026

2038-01-19

The last date a MySQL TIMESTAMP can hold. DATETIME runs to the year 9999, and the two land in different Snowflake types with different time zone behavior.

MySQL 8.4 Reference Manual, read 6 September 2026

16 MB / 8 MB

Default connector ceilings for LONGTEXT and for LONGBLOB, against a MySQL maximum of 4 GB for each. Both are raisable and neither is raised for you.

Openflow Connector for MySQL data mapping, read 6 September 2026

How to migrate MySQL to Snowflake in six steps

  1. 01

    Check the version and the host before anything else

    Two questions decide whether the free first-party option exists for you. Is this MySQL 8 or later, and can you actually set binlog_row_metadata to full? On Azure Database for MySQL the answer to the second is no without a Microsoft support ticket, and on MySQL 5.7 the answer to the first is no until you upgrade. Both are half an hour of checking that can save a month of the wrong plan.

  2. 02

    Configure the binary log deliberately, not minimally

    Snowflake needs log_bin on, binlog_format set to row, binlog_row_image full, binlog_row_metadata full, and binlog_row_value_options left empty. Set binlog_expire_logs_seconds to at least 259200. On RDS that means the retention procedure with 72 hours rather than the 24 in the documented example, because retention is what decides whether a broken weekend costs you a resume or a full re-snapshot.

  3. 03

    Inventory the types that actually differ

    One query against information_schema.columns, grouping every type outside the ordinary scalar set. On most MySQL schemas that returns a handful of types across a few dozen columns: the DECIMALs wider than 38 digits, every TINYINT(1) and BIT, the SET and ENUM columns, the spatial columns, and the LONGTEXT and LONGBLOB rows near the connector ceiling. Those columns carry essentially the whole semantic risk of the project.

  4. 04

    Decide what your booleans mean

    This is the decision no tool makes for you and the one that changes reported numbers. Query each TINYINT(1) for its distinct values. If the only values are 0 and 1, cast to BOOLEAN in the target and move on. If anything else appears, and on an old schema it usually does, you have to decide per column whether 2 means true, means a third state, or means a bug somebody wrote in 2016. Do it before the load, not after somebody queries it.

  5. 05

    Write the target DDL by hand for the flagged columns

    An explicit NUMBER(38,s) for every wide DECIMAL, a BOOLEAN cast for the flags, a real decision on every SET column, raised size limits for the large objects that need them, and TIMESTAMP_NTZ or TIMESTAMP_TZ spelled out rather than inherited. Let the tool generate everything else. This is a day of work that removes most of the reloads.

  6. 06

    Reconcile on values, never on row counts

    Per table, compare the row count, the SUM of every numeric column, MIN and MAX of every date, a count grouped by day, and a count grouped by each boolean flag. That last one is the check that catches the TINYINT problem. Row counts reconcile perfectly on a load that shortened three decimals, turned every flag into hex and dropped the spatial columns into strings.

Who moves MySQL into Snowflake, and why

Reporting that has outgrown the application database

The most common reason this gets funded. Analysts running wide scans against the MySQL instance that also serves the product, and an engineer who has been asking for it to stop for a year. Columnar storage solves it properly rather than by adding another index.

A SaaS product reporting across many tenants

MySQL is the default database behind a great many US SaaS applications, and cross-tenant analytics is exactly the query shape it handles worst. Moving a read-only copy to Snowflake is usually cheaper than sharding the source further.

Joining product data to SaaS data already in Snowflake

The warehouse already holds Salesforce, Stripe or NetSuite data, and the MySQL application database is the last source that cannot be compared against the rest of the business.

Consolidating databases after an acquisition

Estates grown by acquisition often run several MySQL instances with overlapping schemas and different conventions for the same flag. Snowflake becomes the first place they can be queried together, which is also where the boolean question above stops being theoretical.

Getting off a MySQL 5.7 instance nobody wants to touch

Sometimes the warehouse project is the forcing event for the upgrade rather than the other way round, because the first-party connector needs MySQL 8. Worth sequencing deliberately instead of discovering it halfway through.

Keeping both systems live indefinitely

The outcome nobody plans for and most teams reach, because the application is not going anywhere. The one-time move quietly becomes an ongoing sync somebody has to operate for years, which is a different purchase from a migration.

Five jobs where you should not pick us

A comparison page that never says the competition wins is an advert. These are the cases where we are the wrong answer and something on the list above is the right one.

  • A genuine one-time lift with no ongoing sync. Export to Parquet and use COPY INTO. That is what it is for, it is free, and it costs less than we do.
  • Sub-second replication latency from MySQL across dozens of schemas. That is the streaming CDC market and the specialists there earn their license fee.
  • Air gapped environments with no outbound network. We are a hosted service. If nothing may leave your network, this is the wrong shape of product entirely.
  • Teams who need heavy in-warehouse modelling as well as the pipeline. Land the data with us if you like, but the transformation layer belongs in dbt or Matillion.
  • Capturing changes into Kafka for consumers other than Snowflake. Debezium is free, it is the standard, and it is better at that specific job than we are.

Four questions to ask any vendor on this list

What do you do with a TINYINT(1)?

The fastest way to find out whether a vendor has actually run this route. The honest answer is that it depends on the column's distinct values and needs a decision per column. An answer of "we map it to boolean automatically" means every row holding 2 changes meaning silently, and an answer of "we keep it as an integer" means your boolean logic has to be rewritten in the warehouse. Both can be right. Not knowing there is a question is not.

What happens when a DECIMAL is wider than Snowflake allows?

Snowflake's own two connectors answer this differently, so a vendor building on either has inherited a behavior rather than chosen one. Ask whether the load fails, truncates, or converts the column to text, and ask them to show you which. Truncation is the dangerous answer because the result still looks like a number.

Which binlog settings do you require, and have you checked mine?

Ask them to name the settings rather than confirm that they need some. If binlog_row_metadata is on the list, ask what happens on Azure Database for MySQL, where it cannot be changed without a Microsoft support ticket. A vendor who has run this route in production will know that immediately.

What does the backfill cost, separately from steady state?

A migration backfill is not a normal month. On row or event based pricing it is the largest month you will ever have, and on credit based pricing it is a sustained spike in warehouse time. Ask the vendor to price the backfill plus two reloads, because there will be reloads while the type mapping is corrected.

Questions buyers ask about MySQL to Snowflake migration

How do I migrate data from MySQL to Snowflake?
Create the target tables yourself, run a backfill, then keep the two in sync from the binary log until you can retire the source. The step almost everyone skips is checking the source configuration first, because Snowflake's own connector needs four binlog settings and one of them cannot be changed at all on Azure Database for MySQL without a Microsoft support ticket.
How do I connect MySQL to Snowflake?
There is no direct link. Snowflake cannot query MySQL and MySQL cannot write to Snowflake, so something has to sit between them: Snowflake Openflow, a managed pipeline such as Fivetran or AWS DMS, an open source reader like Debezium, or a scheduled export that Snowflake loads with COPY INTO. Every tool on this page is that middle piece.
What is the best MySQL to Snowflake connector?
Snowflake Openflow is the first-party answer and the most likely to stay current, provided your source qualifies. It requires MySQL 8 or later, so a MySQL 5.7 instance is out before you compare features. It also needs binlog_row_metadata set to full, which some managed hosts do not let you set. Check both before shortlisting anything.
How does MySQL to Snowflake replication work?
The connector reads MySQL's binary log, which is the same stream a replica reads. Snowflake requires row-based logging with full row images and full row metadata, so the log carries column names, keys and every column value rather than a statement. That stream is applied to Snowflake as inserts, updates and deletes after the initial snapshot completes.
How much does a MySQL to Snowflake migration cost?
Three bills, and the connector is usually the smallest. You pay for Snowflake warehouse time across the backfill and every reload while the mapping is corrected, for engineering time on the type decisions no tool makes for you, and sometimes for a source upgrade. Budget at least three full reloads, because the first two will be wrong in ways row counts do not reveal.
Does Snowflake use MySQL?
No. Snowflake is a columnar analytic warehouse with its own SQL dialect and its own storage engine, not a MySQL fork and not MySQL compatible. Most MySQL SQL runs unchanged because both follow the standard for ordinary queries, but the type system, the boolean handling and the constraint enforcement all differ, which is what makes the mapping worth checking.
How does MySQL to Snowflake data type mapping work?
Most types have an obvious target and a non-obvious consequence. MySQL DECIMAL reaches 65 digits and Snowflake stops at 38. MySQL BOOL is really TINYINT and arrives as a number, not a boolean. BIT arrives as a hexadecimal string. The table further down gives every mapping and what each one costs you.
Can I use AWS DMS for MySQL to Snowflake?
Yes, and it is a reasonable pick if the MySQL instance already lives in AWS on RDS, Aurora or EC2. You run and size a replication instance that bills by the hour whether or not data is moving, and its type conversion defaults are a third mapping to audit rather than a tie-breaker between the two Snowflake publishes.
Should I use Fivetran for MySQL to Snowflake?
Fivetran suits teams who want the pipeline to be somebody else's problem and have predictable volume. Price the backfill separately from steady state. A migration backfill is the largest active-row month you will ever have, and every reload while you correct the type mapping bills again at that same scale.
How do I load data from MySQL to Snowflake without a connector?
Export to compressed CSV or Parquet, stage the files, and run COPY INTO. It is cheap, it is fully under your control, and for a one-time lift with no ongoing sync it beats every managed tool on price. What it does not give you is change capture, so the moment you need the two systems to agree tomorrow as well, you are back to the list above.

For the people cost that dominates every migration program, read what a data migration really costs. For the same source moved to a different warehouse, see MySQL to BigQuery, and for the wider vendor landscape, the best data integration tools.

Move MySQL into Snowflake once, then keep the two in agreement

Map the fields once, run the backfill, then let the same mapping run incrementally with retries, alerts and per-record logs. From $49 a month, not metered by rows.

Try the live demo

No credit card required.