Beginner~12 min setupProductivity & CRMVerified April 2026
Google Sheets logo
Salesforce logo

How to Sync Contacts Between Salesforce and Google Sheets with Make

Bi-directional automation that updates Google Sheets when Salesforce contacts change, and updates Salesforce when Sheet rows are modified.

Steps and UI details are based on platform versions at time of writing — check each platform for the latest interface.

Best for

Teams needing real-time bi-directional contact sync with custom field transformations and error handling.

Not ideal for

Simple one-way data imports or teams without technical resources to configure loop prevention filters.

Sync type

polling

Use case type

sync

Real-World Example

💡

A 25-person B2B agency uses this to keep their Google Sheet prospect tracker in sync with Salesforce contacts. Sales reps update phone numbers and notes in Sheets during calls, while the marketing team manages email addresses and lead status in Salesforce. Before automation, they manually copied changes twice daily and frequently overwrote each other's updates, losing prospect notes and contact details.

What Will This Cost?

Drag the slider to your expected monthly volume.

/mo
505005K50K

Each platform counts differently — Zapier: 1 task per trigger. Make: 1 operation per module per record. n8n: 1 execution per run.

Prices shown for annual billing. Based on published pricing as of April 2026.

Estimated ROI

1000

min saved/mo

$583

labor value/mo

Free

no platform cost

Based on ~2 min manual effort per operation at $35/hr fully loaded labor cost.

Implementation

Skip the setup

Import this workflow directly into Make

Copy the pre-built Make blueprint and paste it straight into Make. All modules, filters, and field mappings are already configured — you just need to connect your accounts.

Before You Start

Make sure you have everything ready.

Salesforce admin access with API permissions enabled
Google Sheet with contact data and consistent ID column structure
Make account with sufficient operations for your sync volume
Matching field structure between Salesforce contacts and Sheet columns
Backup of your data before implementing bi-directional sync

Field Mapping

Map these fields between your apps.

FieldAPI Name
Required
Salesforce Contact IDId
Email AddressEmail
First NameFirstName
Last NameLastName
2 optional fields▸ show
Phone NumberPhone
Company NameAccount.Name

Step-by-Step Setup

1

Dashboard > Create Scenario > Add Module

Create New Scenario

Start a new Make scenario to house both sync directions. You'll build two separate flows in the same scenario to handle updates from each platform.

  1. 1Click 'Create a new scenario' from the Make dashboard
  2. 2Click the large + button in the center of the canvas
  3. 3Type 'Salesforce' in the app search box
  4. 4Select 'Salesforce' from the results
What you should see: You should see the Salesforce module icon on your canvas with a configuration panel open on the right.
2

Salesforce Module > Configuration Panel

Configure Salesforce Contact Trigger

Set up the trigger to fire when any contact record changes in Salesforce. This handles one direction of the sync - Salesforce to Sheets.

  1. 1Select 'Watch Records' from the Salesforce trigger list
  2. 2Click 'Create a connection' and enter your Salesforce credentials
  3. 3Set Object Type to 'Contact'
  4. 4Choose 'Updated' from the Watch for dropdown
  5. 5Set Max number of records to 10
What you should see: The module shows 'Salesforce: Watch Records (Contact)' and displays a green connection status.
Common mistake — Don't select 'Created and Updated' - this creates duplicate triggers for new contacts that can cause infinite loops.
Make
+
click +
search apps
Google Sheets
GO
Google Sheets
Configure Salesforce Contact…
Google Sheets
GO
module added
3

Canvas > Add Module > Google Sheets > Update a Row

Add Google Sheets Update Module

Configure the action that updates your Google Sheet when Salesforce contacts change. This completes the first sync direction.

  1. 1Click the + button to the right of the Salesforce module
  2. 2Search for and select 'Google Sheets'
  3. 3Choose 'Update a Row' from the actions list
  4. 4Connect your Google account when prompted
  5. 5Select your target spreadsheet and worksheet
What you should see: A Google Sheets module appears connected to Salesforce, showing 'Google Sheets: Update a Row' in the module title.
4

Google Sheets Module > Field Mapping Panel

Map Salesforce to Sheets Fields

Configure which Salesforce contact fields update which columns in your Google Sheet. Use the row identifier to match records correctly.

  1. 1Set Row number field to map to your ID column (usually column A)
  2. 2Click in the Email field and select 'Email' from Salesforce data
  3. 3Map 'FirstName' to your First Name column
  4. 4Map 'LastName' to your Last Name column
  5. 5Map 'Phone' to your Phone column
What you should see: Each field shows a mapped Salesforce value with the characteristic purple pills indicating dynamic data.
Common mistake — The Row number must match your Salesforce ID - if this is wrong, Make will create new rows instead of updating existing ones.
Google Sheets fields
Column A
Column B
Email
Status
Notes
available as variables:
1.props.Column A
1.props.Column B
1.props.Email
1.props.Status
1.props.Notes
5

Canvas > New Branch > Google Sheets > Watch Rows

Add Second Branch for Sheets to Salesforce

Create the reverse sync direction by adding a Google Sheets trigger. This starts the second automation flow in the same scenario.

  1. 1Click the + button in an empty area of the canvas
  2. 2Select 'Google Sheets' from the app list
  3. 3Choose 'Watch Rows' from the trigger options
  4. 4Select the same spreadsheet and worksheet
  5. 5Set Table contains headers to 'Yes'
What you should see: A second, unconnected Google Sheets module appears on your canvas, separate from the first flow.
Common mistake — Don't connect this to your existing flow - it should be a separate branch for the opposite sync direction.
6

Second Branch > Add Module > Salesforce > Update Record

Add Salesforce Update Module

Configure the action that updates Salesforce contacts when Google Sheets rows change. This completes the bi-directional sync setup.

  1. 1Click the + button after the Google Sheets Watch module
  2. 2Select 'Salesforce' from the apps
  3. 3Choose 'Update a Record' from the actions
  4. 4Set Record Type to 'Contact'
  5. 5Use the same Salesforce connection from step 2
What you should see: You now have two separate flows: Salesforce→Sheets and Sheets→Salesforce, both visible on the canvas.
7

Salesforce Update Module > Field Mapping

Map Sheets to Salesforce Fields

Configure the field mapping for updates flowing from Google Sheets back to Salesforce. Use the ID field to identify which contact to update.

  1. 1Set Record ID to map to your Salesforce ID column from Sheets
  2. 2Map the Email column to Salesforce 'Email' field
  3. 3Map First Name column to 'FirstName'
  4. 4Map Last Name column to 'LastName'
  5. 5Map Phone column to 'Phone'
What you should see: The Salesforce update module shows all fields mapped with blue pills indicating Google Sheets data sources.
Common mistake — Record ID must point to the column containing Salesforce contact IDs - usually column A in your setup.
8

Connection Line > Right Click > Set up Filter

Add Loop Prevention Filters

Prevent infinite sync loops by adding filters that detect when changes originate from Make itself. Without these, updates will bounce back and forth continuously.

  1. 1Right-click the line between Salesforce trigger and Sheets update
  2. 2Select 'Set up a filter'
  3. 3Name it 'Not from Make' and set condition 'LastModifiedBy Name' not equal to your Make user
  4. 4Repeat for the Sheets→Salesforce flow with appropriate Sheet metadata
What you should see: Small funnel icons appear on both connection lines, indicating active filters to prevent loops.
Common mistake — Without loop prevention, your scenario will create an infinite update cycle that burns through your operation quota in minutes.
Google Sheets
GO
trigger
filter
Condition
matches criteria?
yes — passes through
no — skipped
Salesforce
SA
notified
9

Module Settings > Error Handling Tab

Configure Error Handling

Set up error handling to manage API failures and rate limits gracefully. This prevents the entire sync from breaking when individual records fail.

  1. 1Click on each action module (not triggers)
  2. 2Click the wrench icon in the module header
  3. 3Set 'Error handling' to 'Break'
  4. 4Enable 'Store incomplete executions'
  5. 5Set retry attempts to 3
What you should see: Each action module shows a small warning triangle icon indicating error handling is configured.
10

Bottom Bar > Run Once > Execution History

Test Both Sync Directions

Run controlled tests to verify both directions work correctly before enabling the full automation. Test with non-critical data first.

  1. 1Click 'Run once' at the bottom of the screen
  2. 2Update a test contact in Salesforce and verify the Sheet updates
  3. 3Modify the same row in Sheets and confirm Salesforce reflects the change
  4. 4Check the execution log for any errors or warnings
  5. 5Verify no duplicate updates occurred
What you should see: Both test updates should complete successfully with green checkmarks in the execution log, and changes should appear in both systems.
Common mistake — Test with records you can safely modify - avoid using active prospect or customer data during testing.
Make
▶ Run once
executed
Google Sheets
Salesforce
Salesforce
🔔 notification
received
11

Bottom Bar > Schedule Settings > Scenario Toggle

Schedule and Activate

Enable the scenario to run automatically and set appropriate scheduling intervals. Balance sync speed with API rate limits and operation usage.

  1. 1Click the clock icon at the bottom left
  2. 2Set interval to 'Every 5 minutes' for near real-time sync
  3. 3Toggle the scenario ON using the switch at bottom left
  4. 4Click 'Save' to preserve all configurations
  5. 5Monitor the first few automatic runs in the execution history
What you should see: The scenario shows 'ON' status with a green indicator, and scheduled executions appear in your dashboard.
Common mistake — Don't set intervals shorter than 2 minutes - you'll hit rate limits on both Salesforce and Google Sheets APIs.

Drop this into a Make custom function.

JavaScript — Custom Function{{if(contains("LastModifiedBy.Name"; "[email protected]"); "skip"; "process")}}
▸ Show code
{{if(contains("LastModifiedBy.Name"; "[email protected]"); "skip"; "process")}}
// Use this filter formula to skip updates made by data import tools, preventing sync conflicts during bulk operations

... expand to see full code

{{if(contains("LastModifiedBy.Name"; "[email protected]"); "skip"; "process")}}

// Use this filter formula to skip updates made by data import tools, preventing sync conflicts during bulk operations

Scaling Beyond 500+ contact updates/day+ Records

If your volume exceeds 500+ contact updates/day records, apply these adjustments.

1

Implement Batching

Use Make's aggregator modules to group multiple contact updates into single API calls. This reduces operation usage by 60-70% and helps avoid rate limits on both platforms.

2

Stagger Sync Directions

Run Salesforce-to-Sheets sync every 5 minutes and Sheets-to-Salesforce every 15 minutes. This prevents API conflicts and reduces the chance of hitting concurrent request limits.

3

Add Conditional Processing

Only sync contacts modified in the last 24 hours using date filters. This prevents unnecessary API calls for unchanged records and dramatically reduces operation consumption.

Going live

Production Checklist

Before you turn this on for real, confirm each item.

Troubleshooting

Common errors and how to fix them.

Frequently Asked Questions

Common questions about this workflow.

Analysis

VerdictWhy Make for this workflow

Use Make for this if you need true bi-directional sync with custom field transformations and complex filtering. Make's visual builder makes it easy to see both sync directions in one scenario, and its error handling prevents cascading failures when APIs hiccup. Skip Make if you just need simple one-way imports - Zapier's contact management triggers are more reliable for basic Salesforce-to-Sheets workflows.

Cost

This workflow burns 4 operations per sync cycle - 2 for triggers, 2 for updates. At 200 contact changes per month, that's 800 operations total. Make's Core plan ($9/month, 10k operations) handles this easily with room to spare. Zapier would cost $20/month for their Starter plan to get the same Salesforce features. N8n is free but requires hosting, which adds $20+ monthly for reliable uptime.

Tradeoffs

Zapier handles Salesforce field mapping better - their interface auto-suggests contact fields and validates picklist values during setup. N8n's Salesforce node supports bulk operations natively, so it's faster for syncing 100+ contacts at once. But Make's router system lets you build complex conditional logic - like syncing VIP contacts immediately but batching regular contacts every hour - without needing separate scenarios.

Google Sheets API rate limits hit hard at 300 requests per minute, which means 5-minute polling intervals minimum for reliable sync. Salesforce's API sometimes returns stale data for 30-60 seconds after updates, causing sync delays that look like failures. The biggest gotcha: Salesforce contact merging breaks your ID mapping completely - when contacts merge, your Sheet references orphaned IDs that no longer exist.

Ideas for what to build next

  • Add Slack Notifications for VIP UpdatesCreate a filter for high-value contacts and send team notifications when their information changes in either system.
  • Build Automated Lead Scoring SyncSync calculated lead scores from Sheets back to a custom Salesforce field to trigger automated follow-up sequences.
  • Create Audit Trail in AirtableLog every sync operation with timestamps and field changes to maintain a complete audit trail for compliance and debugging.

Related guides

Was this guide helpful?
Google Sheets + Salesforce overviewMake profile →