HOW-TO · DATA SYNC

Move Salesforce records into MySQL on a schedule.

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

An internal tool or a customer-facing app built on MySQL sometimes needs a working copy of Salesforce data, without giving that app direct Salesforce API access. Data Sync pulls it with SOQL and lands it mapped into a MySQL table on a schedule.

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 Salesforce connection and a MySQL connection, open Pipelines, Build, New Sync, pick Salesforce as source, write a SOQL query, pick MySQL as target, map fields, choose Insert, Update or Upsert, Dry Run, then save as a job. Pipelines tier.

Why a MySQL app needs Salesforce data at all

Giving an internal or customer-facing app direct Salesforce API access means managing rate limits, API versioning, and a second authentication surface inside application code that has nothing to do with sales data otherwise. A scheduled sync that lands a flattened, mapped copy in MySQL avoids all of that: the app just queries a normal table.

Before you start

Steps

  1. Add both connections under Databases.
  2. Open Pipelines → Build and click New Sync.
  3. On the left, pick the Salesforce connection and write your SOQL query.
  4. On the right, pick the MySQL 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, set MATCH ON to the Salesforce record Id.
  8. Click Dry Run, then Save as a job.

A worked example

Feeding an internal renewal-tracking tool built on MySQL from Salesforce Opportunities:

SELECT Id, Account.Name, Amount, CloseDate, StageName, Owner.Name
FROM Opportunity
WHERE CloseDate <= NEXT_N_DAYS:60
AND IsClosed = false;

Target renewals.opportunities in MySQL, MODE Upsert, MATCH ON the Salesforce Id. QueryFlow handles the upsert into MySQL on that key, so a stage change or a pushed close date updates the existing row instead of creating a second copy of the same opportunity. Schedule it every few hours to keep the renewal tool aligned with reps' actual pipeline updates.

A gotcha worth knowing about relationship fields

A field like Account.Name comes back through SOQL as a nested value in the API response, and QueryFlow flattens it for mapping, but it's read-only data as far as this sync is concerned, you can't write back to Salesforce through the same mapping. If the internal tool needs to push updates the other direction, that's a separate sync built with MySQL as the source and Salesforce as the target.

What this doesn't do

This doesn't replicate Salesforce validation rules, workflow automation, or field-level security into MySQL, it copies the field values a SOQL query can see with the connected user's permissions. If MySQL-side users shouldn't see every field a sales rep can, filter the SOQL query and the mapping accordingly rather than assuming the sync applies any access control on its own.

Picking a stable key when records can be merged or reparented

Salesforce record Ids are stable and unique, which makes them a safer MATCH ON than a business field like an opportunity name that a rep might edit. The one edge case worth knowing: if Salesforce records get merged (two duplicate Accounts combined into one), the surviving Id stays valid but the merged-away Id disappears from future syncs, leaving a stale row in MySQL that a periodic reconciliation query can catch.

Why not just use Salesforce Connect or an AppExchange tool

Salesforce Connect and various AppExchange middleware options exist for exactly this kind of integration, and they're worth it if MySQL access needs to happen live, from inside Salesforce, or across many objects with complex bidirectional logic. For a straightforward one-way pull of a few objects into an internal tool's own database, that's meaningfully more setup and licensing than a scheduled sync needs to solve the same problem.

Keeping the SOQL query itself maintainable

A SOQL query with several relationship traversals and a handful of filter conditions is easy to write once and hard to remember the reasoning behind a year later. A short comment at the top of the query, why this filter, why this date window, saves the next person from re-deriving the logic when a report starts looking wrong and someone has to trace it back to this sync.

Handling Salesforce sandbox versus production

If the team tests changes in a Salesforce sandbox before touching production, it's worth having two separate connections in QueryFlow, one pointed at each, rather than repointing a single connection back and forth. That way a sync built and verified against sandbox data can be pointed at the production connection deliberately, as one clear step, instead of relying on remembering to switch a shared connection's credentials back afterward.

What happens when a field gets deprecated in Salesforce

Admins occasionally retire a custom field, replacing Contract_End_Date__c with a renamed or restructured equivalent, and a SOQL query referencing the old field name starts failing outright rather than quietly returning nulls. Salesforce release notes and a Setup-level deprecation warning usually give advance notice; treating those as a trigger to review any SOQL-based syncs referencing the field avoids a scheduled job breaking with no warning on the day the field disappears.

Rate limits worth knowing about

Salesforce enforces API call limits per 24-hour period based on the org's edition and license count, and a SOQL query pulling a large result set counts against that the same way any API call does. For a scheduled sync running every few hours against a reasonably sized Opportunity set, this is rarely a real constraint, but it's worth checking Salesforce Setup's API usage page if a sync starts failing with a limit-related error rather than a query error.

What this costs against Fivetran

Fivetran's pricing page (September 26, 2026) meters Salesforce as a standard connector by monthly active rows, 500,000 free, then a $5 base charge per connection between 1 and 1,000,000 MAR, usage pricing above that behind a quote. A renewal-tracking sync touching a few thousand open opportunities a month sits well inside the free tier either way, which makes QueryFlow's flat $199.99-a-year Pipelines price mostly relevant if the account has several syncs running at once rather than just this one.

Comparison

QueryFlow Data SyncFivetran
Pricing$199.99/yr flat (Pipelines), covers all your syncsFree under 500,000 MAR per connector, then $5 base + usage
Query languageReal SOQL you write and seeManaged connector, no query exposed
SetupTwo connections, one mapped syncGuided Salesforce connector wizard
Best fitOne or a few internal-tool feedsSalesforce as one of many managed sources

Check it worked

Run Dry Run and compare a few records against Salesforce directly. After a real run, check the job's history for row counts and any listed errors.

Troubleshooting

If you seeFix
Choose at least one key fieldSet MATCH ON to the Salesforce record Id.
A merged Salesforce record still shows old data in MySQLExpected; the old Id disappears from future syncs. Reconcile stale rows periodically.
A relationship field like Account.Name is blankConfirm the connected Salesforce user has read access to the related object.

Sources

Sync Salesforce to BigQuery MySQL Mac client Every warehouse, one client Integrations Load a CSV into MySQL. Sync Google Sheets to MySQL.
QueryFlow Studio $9.99/mo · $99/yr
QueryFlow Pipelines $29.99/mo · $199.99/yr

Frequently asked

Do I need Salesforce API access beyond a normal login?

The connection uses standard Salesforce API access tied to your login and its permission set; no separate middleware platform or connected app beyond what QueryFlow itself registers is required.

Can I sync related fields, like an Account's name alongside an Opportunity?

Yes, SOQL supports relationship traversal directly in the query, for example Account.Name from an Opportunity record, the same way it works in Salesforce's own reports.

How does Upsert write into MySQL?

An INSERT with ON DUPLICATE KEY UPDATE against the MATCH ON column you choose, MySQL's native mechanism for the same result a MERGE gives on other targets.

Which tier includes this?

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

Keep the internal tool current.

14-day free trial, no card. Real SOQL, mapped and scheduled.

Start 14-day free trial

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