Who calls whom? That question sounds too simple to matter, yet skipping it is behind most bad integration designs. Someone says “let’s use Platform Events” in the first five minutes, and the team spends a week bending the requirement to fit. Choosing a Salesforce integration pattern goes much better when you start from four questions, let the answers narrow the tools, and then check the choice against how Salesforce’s own Integration Patterns guide rates it. Everything below is current to Summer ‘26.
New to the building blocks? Read the integration patterns overview first; it introduces REST, SOAP and events.
The four questions
Ask these in order. By the fourth, the tool usually picks itself.
- Direction. Is Salesforce the caller (outbound) or the one being called (inbound)?
- Timing. Does the caller need a response right now (synchronous), or can it move on (asynchronous)?
- Volume. Is this one record, a few dozen, or millions?
- Ownership. Does the data need to live in Salesforce, or can it stay in the source system?
In a design review or an interview, saying those four questions out loud before naming anything shows you are designing from requirements. It also stops the most common configuration mistake, which is setting up inbound components for an outbound integration. The Named Credentials guide covers that trap in detail.
Inbound: an external system calls Salesforce
| Tool | How it works | Good fit | Poor fit |
|---|---|---|---|
| REST API | JSON, resource-based, synchronous | The default for modern integrations, mobile apps and lightweight CRUD | Very high volume |
| SOAP API | XML with a WSDL contract, synchronous | Legacy consumers and middleware that expects typed contracts | New builds |
| Bulk API 2.0 | Asynchronous, job-based, CSV | Loads and extracts above roughly 2,000 records | Anything that needs an immediate response |
| Composite | Up to 25 subrequests that can reference earlier results | Several dependent steps in one round trip | Large independent workloads |
| Composite Graph | Up to 500 nodes per graph; each graph saves or rolls back as a unit | A parent record and its children saved together | Simple flat operations |
| sObject Collections | Up to 200 records of one operation per call | Bulk-style CRUD without the overhead of a job | Anything above 200 records |
| GraphQL API | Client chooses the fields through a single endpoint | UI-driven reads that would otherwise over-fetch | High-volume writes |
| Pub/Sub API | gRPC publish and subscribe | New event-based integrations | Request and reply |
The Composite family deserves its own look because the three variants behave very differently. The Composite API comparison covers subrequest limits, API call counting and the HTTP 200 trap.
Outbound: Salesforce calls another system
| Tool | How it works | Good fit |
|---|---|---|
| Apex callout | HTTP or SOAP from Apex, sync or async | Full control over logic and error handling |
| External Services | Invocable actions generated from an OpenAPI spec | Low-code orchestration from Flow |
| HTTP Callout action in Flow | Declarative REST call without a full External Services registration | Simple REST calls from Flow |
| Outbound Messages | SOAP XML sent on a field change, with retries for 24 hours | Existing legacy integrations only |
| Event Relay | Forwards Platform Events and Change Data Capture to Amazon EventBridge | Pushing events into AWS |
A few callout rules come up constantly:
- You can’t make a callout after uncommitted DML in the same transaction. The platform throws
CalloutException. - Triggers can’t call out directly, so the work has to move to async Apex.
- A transaction allows 100 callouts and 120 seconds of cumulative callout time.
- A synchronous transaction can enqueue 50 async jobs. Enqueue one job per batch of records, and never one per record.
Data virtualization: leave the data where it lives
Salesforce Connect surfaces external data as External Objects (usually over OData). The records show up in the UI and in SOQL, but nothing is copied and no Salesforce storage is used.
It fits when the source system stays the system of record. It fits poorly when you need large-scale reporting or offline access. External Objects also come with real constraints: limited SOQL support, no roll-up summaries, and the __x suffix on every object name.
The Salesforce guidance is plain: don’t copy data into Salesforce unless it truly has to live there.
Event-driven options
| Tool | Payload and retention | Good fit |
|---|---|---|
| Platform Events | Custom payload up to 1 MB, 72-hour replay | Custom notification contracts and loose coupling |
| Change Data Capture | Fixed record-change payload up to 1 MB, 72-hour replay | Streaming record changes without designing a payload |
| Pub/Sub API | gRPC access to Platform Events, CDC and Real-Time Event Monitoring | All new code-based publish and subscribe work |
| Streaming API (PushTopic, generic events) | Legacy | Existing subscribers only |
Events are asynchronous and loosely coupled, which is what makes them attractive. The Platform Events deep dive explains the publish and subscribe model. Their delivery guarantees are weaker than most people assume, though. The Platform Events reliability guide explains exactly where messages can go missing.
Enterprise tooling
If the company already runs MuleSoft, route integrations through it instead of adding more point-to-point links; you get API management, orchestration and monitoring in one place. Without an existing ESB landscape, the extra licence is usually hard to justify. Salesforce’s guidance now names Informatica alongside it, with MuleSoft covering integration and APIs and Informatica covering enterprise data management and ETL.
A few other tools solve narrower problems. Heroku Connect keeps Salesforce and Heroku Postgres in two-way sync, including large volumes and org-to-org setups. Data 360 (formerly Data Cloud) harmonises data from many sources, resolves identities and offers zero-copy access across orgs. And Flow Orchestration runs long, multi-step processes natively, mixing background, interactive and MuleSoft steps, which can remove the need for middleware altogether.
The official selection matrix
The Salesforce Integration Patterns guide classifies each pattern by type and timing. Process integration covers a business flow that spans systems. Data integration covers the information those systems share. Virtual integration means Salesforce works with external data without storing it.
When Salesforce calls another system
| Type | Timing | Pattern |
|---|---|---|
| Process | Synchronous | Remote Process Invocation — Request and Reply |
| Process | Asynchronous | Remote Process Invocation — Fire and Forget |
| Data | Synchronous | Remote Process Invocation — Request and Reply |
| Data | Asynchronous | UI Update Based on Data Changes |
| Virtual | Synchronous | Data Virtualization |
When another system calls Salesforce
| Type | Timing | Pattern |
|---|---|---|
| Process | Synchronous or asynchronous | Remote Call-In |
| Data | Synchronous | Remote Call-In |
| Data | Asynchronous | Batch Data Synchronization |
How the official guide ranks each solution
The guide grades each technology for each pattern. The rankings are worth memorising because a few of them surprise people.
Request and Reply
| Solution | Rating | Notes |
|---|---|---|
| External Services calling a REST API | Best | Declarative; needs an OpenAPI 2.0 or 3.0 spec |
| Lightning component or page calling a synchronous Apex callout | Best | Use a Continuation when the endpoint may be slow |
| HTTP Callout action in Flow | Good | REST from Flow without a full External Services setup |
| Trigger calling an async callout | Suboptimal | This is really Fire and Forget |
| Batch Apex making synchronous callouts | Suboptimal | Per-batch callout limits get in the way |
A Continuation lets a Lightning component wait on a slow callout without holding a server thread, so a sluggish endpoint doesn’t eat into synchronous Apex limits.
Fire and Forget
| Solution | Rating | Notes |
|---|---|---|
| Flow-driven Platform Events | Best | Rated above Apex-driven events |
| Pub/Sub API | Best | The recommended route for external consumers |
| Change Data Capture | Best | Fully declarative |
| Event Relay | Best | Serverless stream to Amazon EventBridge |
| OmniStudio Integration Procedures | Good | |
| Apex-driven Platform Events | Good | |
| Flow-driven Outbound Messaging | Suboptimal | Legacy; new work should use Flow with Pub/Sub API |
| Async callout from Lightning or a trigger | Suboptimal | You have to build guaranteed delivery yourself |
Remote Call-In
| Solution | Rating | Notes |
|---|---|---|
| Composite API, Composite Graph, REST API, Pub/Sub API, Platform Events | Best | |
| Bulk API 2.0 | Best for bulk | Above roughly 2,000 records |
| GraphQL API | Best for complex reads | Multi-object queries with selective fields |
| SOAP API | Suboptimal | |
| Apex web services and Apex REST services | Suboptimal | Only when you need full transactional control or custom pre-commit logic |
That last row catches a lot of teams. A custom @RestResource endpoint feels like the flexible choice, but the standard APIs are rated higher unless you have a specific reason to own the transaction.
Facts that change designs
- Salesforce can’t join a transaction that spans systems. It rolls back only its own work, so multi-system rollback logic belongs in middleware.
- Salesforce Private Connect (on Hyperforce) gives callouts a private network path when traffic shouldn’t cross the public internet.
- Salesforce uses optimistic locking for edits. It notes when you read a record and warns you at save time if someone else changed it in the meantime.
- Batch data sync has its own rulebook. Record locking, change detection and load ordering are covered in the incremental sync guide.
Quick scenario answers
A nightly sync of 2 million records. Bulk API 2.0. It chunks the data for you and runs as an async job. If the company already has MuleSoft, orchestrate and monitor the job there.
An external system must create an Account and three Contacts atomically. Composite Graph. It works out the parent-before-child order and each graph saves or rolls back as a unit. Plain Composite with @{ref} references also works, but Graph lets each order succeed or fail independently of the others in the same payload.
Real-time inventory from an ERP. Start with no replication. Salesforce Connect keeps the ERP as the system of record with no storage cost. Replicate only if you need reporting at scale, offline access, or the ERP can’t take the query load.
“We can’t lose a single message.” Events alone won’t meet that bar. Store the replay ID of the last event processed, make the subscriber safe to run twice on the same event, and add reconciliation or a middleware queue for anything replay can’t reach.
Answering integration questions well
- Count the requirements in the question before you answer. Multi-part questions are where points are lost.
- Name two or three candidate tools, then commit to one and give the reason. A list without a decision earns half credit.
- Before you finish, check that you addressed every stated constraint: authentication, volume, atomicity and latency.