Salesforce to PostgreSQL
Sync Salesforce opportunities, accounts, contacts, leads and custom objects into your own PostgreSQL database, and keep them current with incremental syncs. Weld authorises with OAuth, lands each object as its own table, and connects to Postgres over SSL or an SSH tunnel.
Checked against Weld and vendor docs on
- opportunity7 cols
- account7 cols
- lead7 cols
- contact7 cols
- opportunity_line_item7 cols
- opportunity_contact_role7 cols
- Extract
- Load
- Keep in sync
- salesforce.opportunitySynced
- salesforce.accountSyncing
- salesforce.leadSynced
- salesforce.contactSynced
- salesforce.opportunity_line_itemSynced
- salesforce.opportunity_contact_roleSynced
- Salesforce tables
- 16
- fields, typed
- 112
- agent context included
- MCP
Trusted by data and AI teams
Three ways to get Salesforce data into PostgreSQL
Salesforce's own route into Postgres is Heroku Connect, which syncs with Heroku Postgres. It fits apps built on Heroku that need to read and write Salesforce records. For analytics in a Postgres database you already run, the question is where your database lives.
Heroku Connect
- Best for
- Apps on Heroku that read and write Salesforce data
- Effort
- Medium: a Heroku app, Heroku Postgres and object mappings
- Freshness
- Polling; at least every 10 minutes on the demo plan
- Good to know
- Syncs both ways between Salesforce and a Heroku Postgres database. The free demo plan stops at 10,000 synced rows; the enterprise plan needs a contract. Needs a Salesforce edition with API access.
Custom script on the Salesforce APIs
- Best for
- Teams with engineers to own a pipeline
- Effort
- High: OAuth, pagination, API limits, schema changes
- Freshness
- Whatever you schedule
- Good to know
- Every request counts against the same org wide API limits your other Salesforce integrations use, so the script has to throttle itself.
Weld
- Best for
- Analytics on Salesforce data in a Postgres database you already run
- Effort
- Low: connect Postgres, authorise Salesforce, pick objects
- Freshness
- Incremental syncs on your schedule
- Good to know
- Works with any reachable PostgreSQL server, over SSL or an SSH tunnel. Deleted records are kept and flagged, and syncs slow down at 80% of your API limit.
How to sync Salesforce to PostgreSQL with Weld.
In the app, with the API or an agent.
What lands in PostgreSQL
Every Salesforce table, keys intact.
Salesforce has no fixed table list: Weld offers the objects your Salesforce user can query, standard and custom, and lands each as a table named after the object in snake_case, with fields in snake_case too. Most sales reporting starts from these.
- opportunity7 columns
- idPKstring
- created_datedate
- created_by_idstring
- last_modified_datedate
- last_modified_by_idstring
One row per deal with stage_name, amount, close_date, is_won and is_closed. The base for pipeline, win rate and bookings.
- account7 columns
- idPKstring
- created_datedate
- created_by_idstring
- last_modified_datedate
- last_modified_by_idstring
The companies you sell to. Opportunities and contacts link to it through account_id.
- lead7 columns
- idPKstring
- created_datedate
- created_by_idstring
- last_modified_datedate
- last_modified_by_idstring
Prospects with their status and created_date, and an is_converted flag once they become contacts and opportunities.
- task and event
Calls, emails and meetings logged against records, with activity_date. Useful for activity reporting per rep.
- account
- contact
- lead
- opportunity
- opportunity_line_item
- opportunity_contact_role
- case
- campaign
- campaign_member
- task
- event
- user
- product_2
- pricebook_2
- pricebook_entry
- contract
Monthly bookings from won opportunities.
In PostgreSQL SQL.
Runs in PostgreSQL against the opportunity table Weld lands, here in a schema named salesforce. Deleted opportunities stay in the table with is_deleted set, so they are filtered out.
1select2 date_trunc('month', close_date::date) as month,3 count(*) as won_opportunities,4 round(sum(amount)::numeric, 2) as bookings5from "salesforce"."opportunity"6where is_won7 and not is_deleted8group by 19order by 1 descAsk your agent.
It queries PostgreSQL for you.
Connect Claude, Cursor, ChatGPT or your own agent to Weld over MCP. It reads the Salesforce context, finds the tables it needs and runs the query in PostgreSQL.
How many account rows do we have in PostgreSQL?
Reading the Salesforce context first, so the query uses the right tables and keys.
Things to know.
Before you sync Salesforce.
ELT vs. reverse ETL: Salesforce and PostgreSQL
ELT (Extract, Load, Transform) moves data from Salesforce into PostgreSQL for analysis. This is the approach shown on this page, and the one to use for dashboards, reports, and data models.
Reverse ETL works the other direction: it pushes enriched data from PostgreSQL back into Salesforce. For example, you could sync computed lead scores or customer segments from your warehouse into Salesforce to personalize outreach.
Weld supports both directions, so you can build a complete data loop between Salesforce and PostgreSQL.
PostgreSQL to Salesforce- Heroku Connect needs Heroku Postgres
- Heroku Connect syncs with a Heroku Postgres database attached to a Heroku app, and cannot be used with connection pooling for Heroku Postgres. If your Postgres runs elsewhere, such as on your own servers or another cloud, you need a different route.
- Private databases need a tunnel or allowlist
- Weld connects from a fixed set of IP addresses. For a database on a private network, use the SSH tunnel option, and allowlist those addresses on the SSH server if needed.
- API limits are shared across your org
- Salesforce applies its rate limits to the whole account. When usage reaches 80% of the limit, Weld slows its Salesforce syncs down so your other integrations keep working.
- Deleted records stay, flagged
- Weld reads deleted and archived records as well, so a record removed in Salesforce keeps its row with is_deleted set to true. Objects without a last modified or created date are reloaded in full each run.
- Field names change shape
- Salesforce API names become snake_case columns, so StageName lands as stage_name. Compound address and geolocation fields are skipped; use their component fields.
Keep reading.
Guides, docs and schema.
Common questions.
About Salesforce to PostgreSQL.
Start syncing Salesforce to PostgreSQL.
Set up your Salesforce data pipeline in minutes. No credit card required. Free for 14 days.