Skip to content
adapters.io

How to sync Salesforce to Snowflake the right way

9 min read Data engineering The Adapters team

Last updated July 2026

To sync Salesforce to Snowflake, load your objects with an ELT pattern: pull accounts, contacts, opportunities, and activity into raw Snowflake tables on an incremental schedule, then transform them in the warehouse. Use the SystemModstamp watermark so each run moves only changed rows, which keeps Salesforce API usage low and the data fresh. Push data the other way, from Snowflake back into Salesforce, only when you have a reverse ETL use case.

Field mapping auto-plugged · tap a port to rewire

5 sample records ready

Key takeaways

  • ELT beats ETL here. Load raw first, transform in Snowflake with SQL or dbt, so business logic can change without re-extracting.
  • Go incremental. Pull only rows changed since the last run to spare Salesforce API limits and stay near real time.
  • Warehouse is not reverse ETL. Loading into Snowflake is one direction; sending modeled data back to Salesforce is a separate job.
  • Build for idempotency. Re-running a load should update, not duplicate, so pick a stable key and upsert on it.

What is the best way to sync Salesforce to Snowflake?

For most teams, the best way is an incremental ELT load. Extract Salesforce objects, land them as raw tables in Snowflake, and run transformations inside the warehouse with SQL or dbt. ELT wins because Snowflake does the heavy compute and your business logic can evolve without going back to Salesforce for a fresh extract. Reserve full ETL, where you transform before loading, for cases with strict pre-load rules.

The pattern that keeps this healthy is incremental sync. Instead of pulling every record each run, you pull only the rows that changed since the last one, using the Salesforce SystemModstamp field as a watermark. That single choice is what separates a load that runs every few minutes from one that trips governor limits by lunchtime.

How do you avoid hitting Salesforce API limits?

Avoid API limits by loading incrementally, batching records, and using the Bulk API for large objects. Salesforce enforces a daily API call allowance per org, and a naive full pull of a big Opportunity or Task table can eat through it fast. Incremental loads keyed on SystemModstamp cut call volume to just the changed rows, and the Bulk API moves large sets in far fewer calls than record-by-record queries.

Schedule matters too. Syncing every minute sounds appealing until you multiply it across a dozen objects and a shared API budget. Match the cadence to the decision: near real time for pipeline and activity that a dashboard watches, hourly or nightly for slower dimensions like accounts and users. A data integration platform handles the watermark, batching, and retries so you are not hand-coding around the limit.

Which Salesforce objects should you load first?

Start with the objects your reports actually use, then add the rest. In practice that means the core CRM dimensions and the opportunity fact table first, because that is what revenue and pipeline analytics depend on. The mapping below is a common starting point from Salesforce objects to Snowflake tables.

Salesforce object Snowflake table Load pattern
Account DIM_ACCOUNT Incremental upsert on Id
Contact DIM_CONTACT Incremental upsert on Id
Opportunity FCT_OPPORTUNITY Incremental on SystemModstamp
Task / Event FCT_ACTIVITY Incremental, high volume, use Bulk API
User DIM_USER Full refresh, small and slow-changing

Keep the raw tables close to the source shape and do the renaming, typing, and joins in a transformation layer. That way a new custom field in Salesforce is a column added to the raw table, not a broken pipeline. Once the data is landed and modeled, it is genuinely useful: analysts can ask plain-English questions of the warehouse instead of waiting on a report queue.

What is the difference between ETL and reverse ETL for Snowflake?

ETL and ELT move data into Snowflake for analysis; reverse ETL moves modeled data back out to operational tools like Salesforce. Loading Salesforce into Snowflake is the inbound direction, and it is what powers dashboards, models, and reporting. Reverse ETL is the return trip: you take a scored or enriched table in Snowflake and write it onto Salesforce records so sales sees it in the CRM.

Both can run on the same schedule engine, but they are separate jobs with separate risks. The rule that keeps reverse ETL safe is idempotency: build every job so re-running a failed sync updates existing records rather than creating duplicates or overwriting good data with stale values. Choose a stable external key, upsert on it, and log every write. For more on picking the right direction and cadence, see ETL vs ELT.

How do you keep the Snowflake data secure and fresh?

Keep it secure with encryption in transit and at rest and role-based access in Snowflake so sensitive objects are restricted, and keep it fresh with a schedule matched to how each table is used. Enforce TLS on both connections, apply Snowflake roles so analysts see only what they should, and mask fields that do not belong in a shared warehouse. Freshness is a cadence decision, not a one-time load.

Then watch it. A sync that silently stops is worse than no sync, because the dashboard still renders, just with last week's numbers. Alerting on failed runs and a per-record log turn a quiet failure into a fixable one. The Salesforce to Snowflake connector ships the incremental watermark, retries, alerting, and logging so the warehouse stays current without a babysitter.

Load Salesforce into Snowflake without the API headaches

Incremental, no-code, with retries and a per-record log. Map the pair in the browser and pay a flat price from $49 a month.

Try the live demo