Azure Synapse to Snowflake: A Migration Guide for Dedicated SQL Pools
Quick answer: Convert the code with SnowConvert AI, which is free and supports Synapse tables, views, procedures and functions. Drop distribution, columnstore and partition settings, because Snowflake partitions data automatically, and add clustering keys only to multi-terabyte tables. Export each table to Parquet in ADLS Gen2 with CETAS, load it with COPY INTO through a storage integration, and validate with matching aggregate queries on both platforms. Test MERGE and IDENTITY logic carefully, and use key-pair authentication for any Data Factory pipeline into Snowflake.
Last updated: October 2026
Many teams running Azure Synapse dedicated SQL pools are deciding in 2026 where the warehouse should go next. Microsoft's documentation for dedicated pools now recommends Fabric Data Warehouse for new work, and for teams that already use Snowflake elsewhere in the business, moving the Synapse workload there is the other common option.
This guide is for teams that have chosen Snowflake. It covers the conversion tooling as of October 2026, the parts of a dedicated pool's physical design that have no Snowflake equivalent, the T-SQL behaviour that needs testing, and a data path through ADLS Gen2 that both Microsoft and Snowflake document. If the platform decision is still open, our Fabric vs Snowflake comparison covers it.
Where Synapse stands in October 2026
None of the Microsoft documentation we reviewed announces a retirement date for dedicated SQL pools. What has changed is the guidance. The dedicated SQL pool overview now tells readers who are new to data warehousing to start with Fabric Data Warehouse, and points existing pools to an upgrade path. The Fabric Migration Assistant for Data Warehouse converts a dedicated pool's schema and copies its data, with Copilot help for objects that fail, but Fabric is its only target. It does not help with a move to Snowflake.
Some older migration articles also say that Synapse has no MERGE statement. That is out of date, because Microsoft's current MERGE reference documents the statement for dedicated pools, with restrictions that are covered later in this guide.
Conversion tooling: SnowConvert AI
SnowConvert AI is Snowflake's free code-conversion tool, and Azure Synapse is a generally available source for tables, views, stored procedures and functions. The output follows the same pattern for every source: an assessment report, the converted code, and issue codes that mark code needing a manual fix (EWI) or converted code whose behaviour may differ from the original (FDM).
Synapse support grew during 2026. Release 2.38.0 on 29 July 2026 added data type coverage for Synapse data validation, and release 2.46.0 on 23 September 2026 added full migration support for Azure Synapse. The product's About page still lists data migration and AI code conversion for Synapse as unsupported, so the two pages disagree. We recommend checking the release notes for the version you install before planning around either feature.
Physical design that does not carry over
A dedicated pool stores every distributed table across 60 distributions, using hash or round-robin placement, and copies small replicated tables to every compute node. Much of the tuning work on Synapse happens at this layer: choosing a hash column with many unique values, checking skew with DBCC PDW_SHOWSPACEUSED, and rebuilding a table with CTAS when the choice was wrong, because a distribution column cannot be changed in place.
Snowflake has no user-defined distribution. It divides every table into micro-partitions of 50 MB to 500 MB of uncompressed data automatically and uses their metadata to prune at query time, so the DISTRIBUTION clause, the clustered columnstore index and the partition scheme are all dropped on conversion. The nearest equivalent to an ordered columnstore or a date partition is a clustering key, which Snowflake suggests only for very large tables, typically multiple terabytes, because initial clustering and reclustering consume credits and add storage. Most tables need no clustering key at all, and when one is used Snowflake recommends no more than three or four columns, ordered from lowest to highest cardinality.
| Synapse dedicated pool | Snowflake |
|---|---|
| DISTRIBUTION = HASH, ROUND_ROBIN or REPLICATE | Dropped; micro-partitioning is automatic |
| Clustered columnstore, ordered CCI, table partitions | Dropped; a clustering key only on multi-terabyte tables |
| Workload groups and classifiers | A separate warehouse per workload |
| Pause and resume scripts | AUTO_SUSPEND and AUTO_RESUME, on by default |
| Result set caching (off by default) | Result reuse (on by default, 24 hours) |
| Serverless SQL views over ADLS | Iceberg tables over the same storage |
| Synapse pipelines | Azure Data Factory with the Snowflake V2 connector |
T-SQL that needs testing
MERGE is supported in dedicated pools, with behaviour specific to Synapse. An update is implemented as a delete and insert pair, WHEN NOT MATCHED INSERT is not supported on tables with IDENTITY columns, and NOT MATCHED BY TARGET requires a hash-distributed target. Microsoft also documents a known issue on older builds, where MERGE could leave rows in the wrong distribution and cause later queries to return wrong results; it was fixed in builds 10.0.15563.0 and 10.0.17829.0. If hash-distributed tables have been maintained with MERGE for years, we recommend running Microsoft's published check before using those tables as the baseline for reconciliation.
IDENTITY values in Synapse are allocated separately in each distribution, so they have gaps by design and do not reflect load order. Microsoft also notes that they are not guaranteed to be unique after IDENTITY_INSERT, a reseed or an update to the distribution column. Load existing surrogate key values into Snowflake as ordinary data, reconcile on business keys, and start any new Snowflake sequence above the current maximum.
Dedicated pools have never supported triggers, table variables, cross-database queries or OFFSET and FETCH, so Synapse code tends to rely on temporary tables, CTAS and WHILE loops. These convert to Snowflake temporary tables, CREATE TABLE AS SELECT and Snowflake Scripting. Loops written only to work around Synapse limits are good candidates for a set-based rewrite during the migration, which leaves less procedural code to maintain afterwards.
Workload management, sizing and caching
Synapse isolates workloads inside one pool with workload groups, classifiers and importance, and the ceiling on concurrent queries depends on the service level: 4 at DW100c, 32 at DW1000c and 128 from DW6000c upwards. In Snowflake the usual design gives each workload its own warehouse, for example one for loading, one for transformation and one for BI, so that each can be sized and suspended separately. Multi-cluster warehouses, which add clusters when queries queue, require Enterprise Edition. We found no published mapping between DWUs and Snowflake warehouse sizes from either vendor, so we recommend sizing from a test run of the real workload.
Two operational habits change. Teams that schedule pause and resume scripts for a dedicated pool can rely on auto-suspend and auto-resume, which are on by default and billed per second with a 60-second minimum each time a warehouse starts. Result set caching, which is off by default in Synapse, has an equivalent in Snowflake that is on by default and keeps a result for 24 hours, provided the query text and the underlying data have not changed. New standard warehouses in Snowflake are Gen2 by default, billed on Azure at 1.25 times the Gen1 credit rate, and that rate belongs in any cost comparison with the current DWU bill.
Moving the data through ADLS Gen2
Microsoft describes CETAS (CREATE EXTERNAL TABLE AS SELECT) as the most cost-effective way to extract data from a dedicated pool to ADLS Gen2, and recommends Parquet. Each table is exported by a single query that runs in parallel across the compute nodes, so the export does not use up the pool's concurrency slots. Partitioned extraction through Data Factory can generate more queries than the limit of 128 active queries, and Microsoft's own example needed DWU6000 to run them.
-- Dedicated SQL pool. Requires a database master key.
CREATE DATABASE SCOPED CREDENTIAL WorkspaceIdentity
WITH IDENTITY = 'managed identity';
CREATE EXTERNAL FILE FORMAT ParquetFF WITH (
FORMAT_TYPE = PARQUET,
DATA_COMPRESSION = 'org.apache.hadoop.io.compress.SnappyCodec'
);
CREATE EXTERNAL DATA SOURCE MigrationLake WITH (
LOCATION = 'abfss://export@<storage-account>.dfs.core.windows.net',
CREDENTIAL = WorkspaceIdentity
);
CREATE EXTERNAL TABLE ext.fact_sales_export WITH (
LOCATION = 'fact_sales/',
DATA_SOURCE = MigrationLake,
FILE_FORMAT = ParquetFF
) AS
SELECT * FROM dbo.fact_sales;
One detail in Microsoft's CETAS reference is easy to miss. Values containing the pipe character, a double quote or a line break can cause rejected rows when CETAS writes Parquet, and free-text columns such as notes or addresses often contain them. Microsoft's workaround is to export those tables to delimited text first and convert the files to Parquet afterwards.
On the Snowflake side, a storage integration lets a stage read ADLS Gen2 without storing a credential in Snowflake. Use the blob.core.windows.net endpoint, which Snowflake specifies for Data Lake Storage Gen2 accounts as well. After the integration is created, DESC STORAGE INTEGRATION returns a consent URL; an Azure administrator accepts it and grants Snowflake's application the Storage Blob Data Reader role on the storage.
CREATE STORAGE INTEGRATION adls_migration
TYPE = EXTERNAL_STAGE
STORAGE_PROVIDER = 'AZURE'
ENABLED = TRUE
AZURE_TENANT_ID = '<tenant-id>'
STORAGE_ALLOWED_LOCATIONS = ('azure://<storage-account>.blob.core.windows.net/export/');
-- Returns AZURE_CONSENT_URL for the Azure administrator to accept
DESC STORAGE INTEGRATION adls_migration;
CREATE STAGE migration.synapse_export
URL = 'azure://<storage-account>.blob.core.windows.net/export/'
STORAGE_INTEGRATION = adls_migration
FILE_FORMAT = (TYPE = PARQUET);
COPY INTO analytics.fact_sales
FROM @migration.synapse_export/fact_sales/
MATCH_BY_COLUMN_NAME = CASE_INSENSITIVE;
Snowflake recommends load files of roughly 100 to 250 MB compressed, advises against files of 100 GB or more, and cannot load in parallel across more files than exist, so check the number and size of the files CETAS produced before running COPY INTO on a large table. Snowflake does not charge for loading data in, while Azure may charge for transfers between regions, so we recommend placing the export storage account in the same Azure region as the Snowflake account.
Data that serverless SQL pools already query in the lake may not need to move at all. Snowflake Iceberg tables are available in all regions, Azure included, and can be created over Parquet data in the same ADLS storage. Two Azure limitations apply in October 2026: server-side encryption on Azure external volumes is not supported, and private VNet connectivity for Iceberg requires a request to Snowflake support or the account team.
Pipelines and authentication
Synapse pipelines run on the same data integration engine as Azure Data Factory, and Microsoft's Snowflake connector page applies to both. The V1 Snowflake connector is now listed as removed, so pipelines need the V2 connector, which connects with an account identifier, warehouse, database, schema and role in place of a connection string. V2 also changes how some types arrive: NUMBER(p,0) is read as Decimal, and all three Snowflake timestamp types are read as DateTimeOffset, which matters for any pipeline that reads from Snowflake.
Authentication is the change most likely to break a pipeline built from an older guide. The V2 connector defaults to Basic authentication, meaning a username and password, and Snowflake's MFA rollout blocks password sign-in for all non-human users in Phase 3, which Snowflake scheduled for August to October 2026. We recommend creating a dedicated SERVICE user with key-pair authentication and selecting KeyPair in the linked service from the start.
Validating before cutover
Synapse and Snowflake use different hash functions, and CHECKSUM_AGG is not supported in dedicated pools, so row-hash comparisons across the two platforms take real effort to set up. Aggregate comparisons are simpler and catch most loading errors. Run the same query against each table on both platforms and compare the results.
-- Run on Synapse (dbo.fact_sales) and on Snowflake (analytics.fact_sales),
-- then compare the two result rows.
SELECT COUNT(*) AS row_count,
COUNT(DISTINCT order_id) AS distinct_orders,
SUM(CAST(net_amount AS DECIMAL(38, 2))) AS net_amount,
MIN(order_date) AS first_order,
MAX(order_date) AS last_order
FROM dbo.fact_sales;
Reconcile on business keys, since IDENTITY values carry no meaning across platforms. SnowConvert AI's release notes record Synapse data validation features added between July and October 2026, which can automate part of this work, and we recommend confirming what the version you install supports. For the steps around the technical work, our Snowflake migration checklist covers planning, cutover and sign-off.
Related Articles
Frequently Asked Questions
Q: Is Azure Synapse Analytics being retired?
Microsoft had not announced a retirement date for dedicated SQL pools in the documentation we reviewed in October 2026. Its documentation recommends Fabric Data Warehouse for new data warehousing work and offers the Fabric Migration Assistant for moving existing dedicated pools to Fabric.
Q: Does SnowConvert AI support Azure Synapse?
Yes. Code conversion for Synapse tables, views, stored procedures and functions is generally available, and the tool is free. Release notes from July to October 2026 add Synapse data validation and migration support, although the product's About page had not been updated to match.
Q: What replaces HASH distribution in Snowflake?
Nothing needs to replace it. Snowflake divides every table into micro-partitions automatically, so DISTRIBUTION, columnstore and partition clauses are dropped. Very large tables, typically several terabytes, may benefit from a clustering key.
Q: What is the best way to export data from a Synapse dedicated pool?
Microsoft recommends CETAS to Parquet files in ADLS Gen2 as the most cost-effective method. It uses one query per table and does not exhaust the pool's concurrency slots. Snowflake can then load the files with COPY INTO through a storage integration.
Q: Why does an ADF pipeline to Snowflake fail with a password error in 2026?
Snowflake's MFA rollout blocks password sign-in for non-human users in Phase 3, scheduled for August to October 2026, and the ADF Snowflake V2 connector defaults to Basic authentication. Switch the linked service to KeyPair with a SERVICE user.
