HOW-TO · DATA SYNC

Move MySQL rows into Redshift on a schedule.

By Chris Davidson, founder of yForest · Updated September 26, 2026

An AWS-native stack often means MySQL (RDS or Aurora) on the operational side and Redshift for analytics. Data Sync maps the two together and runs on a schedule, using IAM-key auth on the Redshift side.

Start 14-day free trial Download on theMac App Store

No credit card. 14 days. Cancel in one click.

macOS 15+ · Apple Silicon native · 14-day free trial · No credit card

Quick answer: Add a MySQL connection and a Redshift connection (IAM access key), open Pipelines, Build, New Sync, pick MySQL as source and Redshift as target, map fields, choose Insert, Update or Upsert, Dry Run, then save as a scheduled job. Pipelines tier.

The AWS-native version of this problem

RDS or Aurora MySQL running the application, Redshift running the warehouse: it's a common enough pairing that AWS ships its own tooling for it, DMS chief among them. DMS is powerful and also genuinely complex to configure correctly, replication instances, endpoints, and task settings that take real study to get right for anything beyond a straightforward one-time migration.

Before you start

Steps

  1. Add the MySQL connection and the Redshift connection (IAM access key) under Databases.
  2. Open Pipelines → Build and click New Sync.
  3. On the left, pick the MySQL connection and table, or write SQL.
  4. On the right, pick the Redshift connection and target table, or create one.
  5. Drag fields across, or click AI Map.
  6. Pick a MODE: Insert, Update or Upsert.
  7. For Update or Upsert, choose a MATCH ON field that's unique per row.
  8. Click Dry Run, then Save as a job.

A worked example

Keeping a Redshift orders table current from an Aurora MySQL source:

SELECT order_id, customer_id, total_cents, status, updated_at
FROM shop.orders
WHERE updated_at >= NOW() - INTERVAL 1 DAY;

Target analytics.orders in Redshift, MODE Upsert, MATCH ON order_id. QueryFlow handles the merge into Redshift on that key, so a status change updates the existing row instead of piling on a duplicate. Schedule it hourly to keep same-day order status visible in Redshift-backed dashboards.

A type gotcha worth knowing

MySQL's DECIMAL and Redshift's DECIMAL generally line up cleanly, but a MySQL TINYINT(1) used as a boolean doesn't map to Redshift's BOOLEAN automatically, it lands as a small integer unless the target column is typed explicitly. If a true/false field like is_paid shows up as 0 or 1 in Redshift, check the target column's type before assuming the data itself is wrong.

What this doesn't do

This is a scheduled batch sync, not log-based CDC off the MySQL binlog, and it won't replicate schema changes automatically. If a table needs sub-minute replication with automatic DDL propagation across dozens of tables, that's the case DMS or a dedicated CDC tool is actually built for, and paying that setup cost is worth it at that scale. For one or a handful of tables synced on an hourly or nightly cadence, that infrastructure is more than the problem calls for.

A note on Redshift compute during the sync

Every MERGE against Redshift runs against your cluster's own compute, whether that's a provisioned cluster or Redshift Serverless. For a moderate incremental sync, that's a small addition to the cluster's normal workload, but if the source query itself does a heavy join or the target table is large and frequently vacuumed, it's worth checking the cluster's query queue during the sync window rather than assuming it's free.

Picking Insert versus Upsert for this pair

An orders table that changes status in place calls for Upsert, as above. A log-style table, an audit trail or event stream that only ever gets new rows and never edits existing ones, doesn't need a MATCH ON at all: Insert with a time-filtered source query is simpler and avoids running a MERGE for a table that never actually has anything to update.

Watching the MySQL side under load

An hourly incremental sync filtered to a recent time window is a light read against MySQL, but a first full-table sync on a large orders table is not, and it's worth running that initial load during a quieter traffic window rather than the middle of a peak sales period. Once the initial load is done, the ongoing incremental syncs are a much smaller query against a much smaller slice of the table.

Why not just replicate at the AWS layer

If the MySQL side is RDS or Aurora, AWS offers its own replication paths, a read replica promoted separately, or Aurora's own cross-region replication, but none of that gets the data into Redshift on its own; it solves availability and read scaling within MySQL, not the warehouse-loading problem this page is actually about. They're complementary, not substitutes.

Sizing the Redshift target ahead of the first load

A table auto-created from the mapping inherits generic defaults, no sort key, no distribution style, which is fine for a small dimension table but noticeably slower for a fact table in the millions of rows once real queries start hitting it. Setting a sensible sort key, usually the date column reports filter on most often, and a distribution style matched to how the table gets joined, before the first real load lands, saves a table rebuild later.

Vacuum and analyze after a large initial load

Redshift's query planner relies on statistics that a large initial load can leave stale, and an un-vacuumed table with heavy deletes or updates from repeated Upsert runs can accumulate dead rows that slow scans down over time. Running VACUUM and ANALYZE on the target table after the first big load, and periodically afterward if the sync runs frequently, is standard Redshift housekeeping this integration doesn't remove the need for.

What this costs against Fivetran and AWS DMS

Fivetran's pricing page (September 26, 2026) puts the free tier at 500,000 MAR, then a $5 base charge per connection between 1 and 1,000,000 MAR, with usage pricing above that behind a quote. AWS DMS bills separately for the replication instance's compute hours, on top of engineering time to configure it correctly, neither of which QueryFlow requires. QueryFlow Pipelines is $199.99 a year flat.

Comparison

QueryFlow Data SyncFivetranAWS DMS
Pricing$199.99/yr flatFree <500k MAR, then $5 base + usage quoteHourly replication-instance compute cost
Setup effortTwo connections, one mapped syncGuided connector wizardReplication instance, endpoints, task config
Where it runsYour MacManaged cloudAWS-managed replication instance
Best fitA handful of tables, hourly or nightlyMany sources, continuous syncLarge-scale, ongoing CDC migrations

Check it worked

Run Dry Run and compare the preview against MySQL. After a real run, check row counts in Redshift and the job's history for any listed errors.

Troubleshooting

If you seeFix
Connection timed outConfirm Redshift is reachable from your Mac's network, the same check any SQL client needs.
Choose at least one key fieldPick a MATCH ON column for Update or Upsert.
Boolean field looks numeric in RedshiftMySQL TINYINT(1) case above; set the target column type explicitly.

Sources

Sync Redshift to Snowflake Redshift Mac client Every warehouse, one client Integrations Load a CSV into Redshift. Sync PostgreSQL to Redshift
QueryFlow Studio $9.99/mo · $99/yr
QueryFlow Pipelines $29.99/mo · $199.99/yr

Frequently asked

Does Redshift need a public endpoint for this to work?

It needs to be reachable from your Mac, either directly or through a VPN or bastion your network already uses for database access. QueryFlow doesn't change your network posture; it connects the way any SQL client would.

What credentials does the Redshift side use?

An IAM access key, matching the auth QueryFlow's background helper already uses for scheduled Redshift jobs, so the same credential setup applies whether the job runs while the app is open or closed.

How does Upsert write into Redshift?

It runs a MERGE on the column you set as MATCH ON, inserting new rows and updating existing ones in the same operation.

Which tier includes this?

Pipelines. Studio covers querying MySQL and Redshift, not building a sync between them.

Skip the DMS setup.

14-day free trial, no card. Two connections, one mapped sync.

Start 14-day free trial

No credit card. 14 days. Cancel in one click.