A full cutover is a project. Mirroring a few tables while you evaluate Snowflake is a sync.
No credit card. 14 days. Cancel in one click.
Quick answer: Add Redshift and Snowflake connections, then build a Data Sync: pick Redshift as the source, write the query for the table you're moving, and map it to a Snowflake table. Run Insert for the first load, then Upsert to keep both systems current. Pipelines tier.
A full Redshift-to-Snowflake migration is a project, not a sync, and this page isn't that. What comes up more often is smaller: a team is evaluating Snowflake, or has already committed to it, and needs specific tables mirrored over while the two systems run side by side for a while. That's a sync problem with a migration flavor, not a one-time cutover.
Moving a customers dimension table over first, since dashboards elsewhere will need it as soon as fact tables start landing in Snowflake too:
-- Redshift source SELECT customer_id, company_name, region, signed_up_at FROM analytics.customers;
-- Snowflake target CREATE TABLE IF NOT EXISTS ANALYTICS.PUBLIC.CUSTOMERS ( CUSTOMER_ID NUMBER, COMPANY_NAME VARCHAR, REGION VARCHAR, SIGNED_UP_AT TIMESTAMP_NTZ );
Run this once as Insert for the initial load, then switch the same sync to Upsert with MATCH ON set to CUSTOMER_ID for ongoing runs, so new customers get added and existing ones stay current while both systems are live.
Compare row counts on both sides after each run, and spot-check a handful of customer IDs directly rather than trusting an aggregate count alone, since a count can match even if a few individual rows landed with the wrong values.
SELECT COUNT(*) AS row_count FROM ANALYTICS.PUBLIC.CUSTOMERS;
| If you see | Fix |
|---|---|
| Timestamp values off by a fixed offset | Redshift and Snowflake handle timezone-aware columns differently; confirm both sides agree on UTC versus local before trusting a diff. |
| Choose at least one key field | Pick a MATCH ON column for Update or Upsert modes. |
| Job fails on the Redshift side | Background jobs against Redshift authenticate with IAM keys rather than a password; confirm those are current. |
Data Sync moves rows. It doesn't carry over Redshift-specific objects like stored procedures, WLM queue configuration, or user grants, and connections themselves have to be re-added by hand rather than imported wholesale. Treat this as the table-by-table mechanism inside a bigger migration plan, not the entire plan.
Dimension tables like customers are small and cheap to move in full every run. A fact table with years of order history is a different problem, moving all of it every time wastes both time and Snowflake compute. Filter the source to a recent window and let Upsert handle both new and changed rows:
-- Redshift source SELECT order_id, customer_id, order_total, status, updated_at FROM analytics.orders WHERE updated_at >= GETDATE() - INTERVAL '7 days';
A 7-day window is usually enough to catch late-arriving updates without re-scanning the entire table's history on every run. If your source system occasionally corrects an order from months back, widen the window periodically, or run a one-time full sync alongside the regular incremental one, rather than assuming a week always covers every edit.
The very first load of a multi-year fact table is the slowest step in the whole process, and it's worth doing separately from the ongoing incremental syncs rather than as the same job. Run the full historical load once, unfiltered, as a dedicated Insert sync, confirm the row count lines up, and only then switch to the smaller windowed Upsert sync for everything going forward. Trying to do both in one sync tends to make the first run painfully slow while adding complexity the ongoing runs don't need.
See also: Integrations Sync BigQuery to Snowflake CSV to Snowflake on Mac.
No, it moves table rows. Redshift-specific objects and permissions aren't part of a Data Sync and need to be recreated separately.
Yes, that's the common pattern: Insert once for the initial load, then Upsert on a schedule to keep Snowflake current.
Only for background jobs against Redshift that need to run with the app closed; interactive syncs use your normal Redshift credentials.
No, connections are re-added by hand in QueryFlow; there's no bulk import from another tool.
14-day free trial, no card. Mirror the tables you need while you evaluate the rest.
No credit card. 14 days. Cancel in one click.