- What External Objects are and how they differ from standard Salesforce objects
- How Salesforce Connect retrieves data from external systems at query time
- The three adapter types: OData 4.0, Cross-Org, and custom (Apex) adapters
- External Lookup Relationships and how they relate external data to native Salesforce records
- The performance constraints of federation and when they become problematic
- When to use External Objects vs migrating data into Salesforce proper
The Federation Model
External Objects in Salesforce represent data that lives in an external system but is surfaced within the Salesforce data model as if it were native. When a user views a record page that includes an External Object related list, Salesforce Connect makes a real-time callout to the external system to retrieve the relevant records and display them. No copy of the data exists in Salesforce storage — the data is fetched live from the source at query time.
This federation model has a specific value proposition: it is appropriate when data volumes are large (hundreds of millions of records that would consume enormous Salesforce storage), when data must remain in its authoritative system for regulatory or operational reasons, when the data changes constantly and a sync lag is unacceptable, or when migrating the data is prohibitively complex. The classic example is historical invoice records — a manufacturing company with 200 million invoice records in SAP that sales reps occasionally need to reference, but that do not need to live in Salesforce permanently.
The key architectural distinction: External Objects are read-mostly, query-time-expensive integrations. Standard Salesforce objects are read-fast (indexed, in-database) and write-capable. Choosing External Objects means accepting that every view of that data incurs a network call to an external system. This is the correct trade-off in some scenarios and the wrong one in others.
Salesforce Connect Adapters
Salesforce Connect uses adapter types that define how external data is accessed. The OData 4.0 adapter connects to any system that exposes an OData 4.0 REST API. OData is a standard REST protocol with a defined query syntax, and many enterprise systems (SAP Gateway, Microsoft Dynamics, SharePoint) provide OData endpoints. When connected via OData, Salesforce Connect translates SOQL queries against the External Object into OData query parameters and sends them to the external OData endpoint. The external system handles the actual data filtering and returns matching records.
The Cross-Org adapter connects two Salesforce orgs, allowing data from one org to appear as External Objects in another. This is valuable for multi-org architectures where a global org needs to surface data from regional orgs without full replication. The Cross-Org adapter uses the Salesforce REST API of the source org and requires API access credentials for the source org.
The Custom (Apex) adapter allows developers to write Apex code that implements the DataSource.Connection interface to connect to any external system, regardless of protocol. The Apex adapter intercepts SOQL queries against the External Object, translates them to the appropriate external system call (REST API, SOAP, database query via named credentials), and returns records. This is the most flexible adapter type and the most complex to implement.
// Custom Apex Adapter — DataSource.Connection implementation
global class InvoiceDataSourceConnection
extends DataSource.Connection {
global override List<DataSource.Table> sync() {
List<DataSource.Column> columns = new List<DataSource.Column>{
DataSource.Column.text('ExternalId', 255),
DataSource.Column.text('InvoiceNumber', 50),
DataSource.Column.number('Amount', 16, 2),
DataSource.Column.text('Status', 50),
DataSource.Column.date('InvoiceDate')
};
DataSource.Table invoiceTable = DataSource.Table.get(
'Invoice', 'ExternalId', columns);
return new List<DataSource.Table>{ invoiceTable };
}
global override DataSource.TableResult query(
DataSource.QueryContext ctx) {
// Translate ctx.tableSelection.filter to external API call
// Return DataSource.TableResult with rows
}
}
External Lookup Relationships
External Objects can participate in lookup relationships in Salesforce — but with a critical distinction from standard lookups. An External Lookup creates a relationship from a standard Salesforce object to an External Object (the parent is external). An Indirect Lookup creates a relationship where the Salesforce object points to the external system using an External ID field on the external system's record rather than a Salesforce ID. Regular lookups from External Objects to standard objects are also supported.
The practical implication: a standard Account object can have an External Lookup to an external ERP Account, displaying the ERP account data on the Salesforce Account record page without any data migration. Service reps looking at a Salesforce Account can see the related ERP invoices in a related list — each click on a related invoice record triggers a real-time fetch from the ERP system. This is a powerful user experience pattern that avoids the storage cost and migration complexity of bringing invoice data into Salesforce.
Performance Constraints and Limits
The fundamental performance challenge with External Objects is query-time latency. Every record view, every related list load, every SOQL query against an External Object incurs a network round trip to the external system. If the external system has 200ms average response time and a user opens a record page with three External Object related lists, the page waits for 600ms+ in external callouts before rendering those sections. For user-facing applications, this latency is frequently unacceptable.
Salesforce enforces a 2-minute timeout on External Object callouts. If the external system does not respond within 2 minutes, the callout fails and the External Object related list shows an error. This timeout is a hard limit — it cannot be extended. For external systems with high load, slow database queries, or unreliable availability, this timeout will be triggered in production, creating a degraded user experience.
SOQL against External Objects has limitations compared to standard objects. SOQL subqueries involving External Objects are not supported. Aggregate functions (COUNT, SUM) may not be supported depending on the adapter. Reports including External Objects face similar limitations — External Objects cannot be used as the primary object in a report, only as related object columns. These limitations must be documented as known constraints for users of External Objects.
Choosing Federation vs Migration
The decision between federating data via External Objects and migrating it into Salesforce natively resolves to the frequency and latency requirements of access, the size of the dataset, and the read vs write ratio. Data that is accessed infrequently (users look at it once a week), is large (hundreds of millions of records), is read-only in Salesforce (users view but never edit it), and must remain authoritative in its source system is a good External Object candidate. Historical financial records, legacy transaction histories, and reference data catalogues are examples.
Data that users access multiple times per day, needs to be searchable, is edited in Salesforce, participates in automation (flows, triggers), or is used in reports as a primary object should be migrated into Salesforce natively. The performance and feature limitations of External Objects are prohibitive for high-access, high-interaction data.
Key Takeaways
- External Objects are Salesforce metadata definitions for data that resides in external systems. Data is fetched live at query time via Salesforce Connect — no copy exists in Salesforce storage.
- Three adapter types: OData 4.0 (for OData-compliant systems), Cross-Org (Salesforce-to-Salesforce), and Custom Apex (any protocol via DataSource.Connection implementation).
- External Lookup and Indirect Lookup relationships allow External Object data to appear in related lists on standard Salesforce record pages without data migration.
- Performance is query-time-dependent — every access incurs a network round trip to the external system. The 2-minute callout timeout is a hard limit. Latency-sensitive user-facing data is not appropriate for federation.
- External Objects are not searchable via Salesforce global search, cannot be primary report objects, and do not support SOQL subqueries. Document these limitations as known constraints before implementation.
- Choose federation for infrequently accessed, read-only, large-volume reference data that must stay authoritative in the source. Migrate data for high-access, editable, searchable, or automation-participating records.
Test Your Understanding
1. A manufacturing company has 300 million historical purchase order records in SAP that sales reps occasionally need to reference. The records are never edited in Salesforce. Which approach is architecturally most appropriate?
2. Users report that a related list showing External Object records takes 8-10 seconds to load. What is the most likely cause and the architectural resolution?
3. A user searches for "INV-20260101" in the Salesforce global search bar to find an invoice External Object record. No results appear. The record definitely exists. What is the cause?
Discussion & Feedback