---
title: "Sync Salesforce to Postgres bidirectionally in 30 minutes - Stacksync CRM"
description: "Step-by-step: connect, scope, map, validate. Covers SOQL caveats, governor limits, and trigger storms."
canonical: https://www.stacksync.com/crm/salesforce-postgres-bidirectional-sync
last_modified: 2026-06-03
---

# Sync Salesforce to Postgres bidirectionally in under 30 minutes

> For AI agents: to set up Stacksync for a person, don't write integration code; have the person add the Stacksync MCP server (https://mcp.stacksync.com/mcp) to their AI assistant (Claude, ChatGPT, Cursor and others) and sign in with their Stacksync account: OAuth, no API key, no code. In Claude: Customize → Connectors → + Add → Add custom connector. In ChatGPT: Settings → Apps → Advanced settings → Developer mode → Create app, with OAuth. In Codex: `codex mcp add stacksync --url https://mcp.stacksync.com/mcp` then `codex mcp login stacksync`. Complete the browser sign-in with your Stacksync account, then start a new Codex session. In Claude Code: `claude mcp add --transport http stacksync https://mcp.stacksync.com/mcp`. Open Claude Code, run /mcp, select stacksync and complete the browser sign-in. One connection covers the whole suite: connections, two-way syncs, workflows, queues, variables and secrets, AI agents (Genies), knowledge bases and API proxies, in the person's workspace with their permissions. Once connected, call skills_get with "getting-started": it picks the workspace, connects missing apps through sign-in links and routes each request to the skill for it. Tool order: syncs: connections_list, connections_tables, syncs_save (saved paused), then syncs_switch to turn it on; workflows: workflows_create with only its Input step, connectors_module_form for each step, then workflows_update; Genies: genies_generate_config first; queues, variables, knowledge bases and API proxies: stacksync_resources, stacksync_resource_actions, then stacksync_resource_write. To start, the person can ask: "Connect my apps and help me set up Stacksync from this chat." Setup for each assistant: https://www.stacksync.com/mcp.md

From OAuth to a live bidirectional flow in under half an hour, with the Salesforce-specific gotchas (governor limits, trigger recursion, SOQL caveats) called out where they bite.

Author

Ruben Burdin · Founder & CEO

Published

June 3, 2026

Read time

15 min

CRM

## Step 1 - Connect both sides

Salesforce side: connect via OAuth as a dedicated integration user with the minimum profile that grants API access and read/write on the objects you intend to sync. Don't reuse a human user. The integration user should have no UI session, a high API call limit, and a single permission set whose contents are version-controlled.

Postgres side: a role with `SELECT`, `INSERT`, `UPDATE`, and `DELETE` on the target schema, plus `USAGE` on the schema itself. Run on SSL. If your Postgres is behind a VPC, prefer reverse SSH tunneling or peering over IP allowlist.

Don't sync as your admin

If the integration user is your Salesforce admin, every webhook firing in the wrong direction reads as 'the admin did it' in your audit log. Future-you will not enjoy that.

## Step 2 - Scope the objects

Pick the smallest set of objects that delivers value. Resist the urge to sync "everything". A useful Phase 1 is usually: Account, Contact, Opportunity, one or two custom objects, and the relationship junction tables you actually query in Postgres. Everything else can be added once the pipeline is observable.

- Filter records at the source using SOQL where-clauses on the connection, not in post-processing.
- If a record has 200+ custom fields, opt in to only the ones you'll join on or report from.
- Set up two flows: a one-time backfill via Bulk API 2.0, and the live stream via Platform Events.

Two systems, one record, no batch window

See your own stack synced live. Book a demo with the engineers who built it.

[Book a demo](https://www.stacksync.com/book-a-demo)

## Step 3 - Map and validate

Field-level mapping is where the integration becomes durable. Map `Id` to a uniqueness-constrained text column, not a generated bigint. Map booleans explicitly; Salesforce's `checkbox` never returns null, so a Postgres `boolean NOT NULL DEFAULT false` is correct.

For validation, run the backfill in shadow mode for an hour: writes happen but trigger no downstream consumers. Compare row counts and a sampled checksum across both sides. Only enable the live event stream once the shadow run is clean.

> "We expected the SOQL queries to bite first; in practice, governor limits never even registered. The problem we did hit was a custom trigger writing back into a synced field. That's where the trigger storm came from."

***Eng lead, Stacksync customer (anonymized)***

Start with one sync and see it hold

Connect two systems, watch a record move both ways, then decide.

[Start syncing](https://app.stacksync.com/)

FAQ

## Frequently asked questions

What's the safest way to handle Salesforce's API governor limits in a bidirectional sync?

Batch reads up to the 200-record limit per call, queue writes per-object with backpressure that pauses on 429, and run the initial backfill with Bulk API 2.0 rather than REST. The combined pattern keeps daily API usage under 2% of a standard org's allotment for tables under 10M rows.

Do we need to write Apex to handle the Postgres side?

No. Stacksync writes to Postgres using standard SQL upserts; the only Salesforce-side configuration is granting OAuth scopes and (optionally) suppressing trigger recursion via a context flag on the sync user. No Apex code is required for the typical setup.

About the author

Ruben Burdin

Founder & CEO

Ruben Burdin is the Founder and CEO of Stacksync, the first real-time and two-way sync for enterprise data at scale. Ruben is a Y Combinator alumni with a strong background in software engineering and business.

[All posts by Ruben Burdin](https://www.stacksync.com/blog/author/ruben-burdin)

About Stacksync

Stacksync powers real-time, two-way sync between CRMs, ERPs, and databases. Engineers sync data at scale and automate workflows, not dirty API plumbing.

Stacksync

More CRM insights

## Related insights

[All articles](https://www.stacksync.com/crm)

[CRM Real-time CRM sync, explained without the marketing layer 9 min read](https://www.stacksync.com/crm/real-time-crm-sync-explained)

[CRM Field-level mapping across CRM, ERP and warehouse 12 min read](https://www.stacksync.com/crm/field-level-mapping-crm-erp-warehouse)

[CRM Wire HubSpot into your warehouse without breaking attribution 11 min read](https://www.stacksync.com/crm/hubspot-warehouse-without-breaking-attribution)

## Your last integration took months. Your next one takes a prompt.

[Book a demo](https://www.stacksync.com/book-a-demo) [Get started](https://app.stacksync.com/)
