ERP Bulk Import Comparison: Bulk API 2.0 vs IDoc vs FBDI vs SuiteTalk vs DMF
Type: ERP Integration
System: Salesforce, SAP S/4HANA, Oracle ERP Cloud, NetSuite, Dynamics 365 F&O
Confidence: 0.88
Sources: 8
Verified: 2026-03-02
Freshness: evolving
TL;DR
- Bottom line: Salesforce Bulk API 2.0 is the most mature and developer-friendly bulk interface; SAP IDoc handles highest volume but is sunset in cloud editions; Oracle FBDI is template-driven with module-specific limits; NetSuite SuiteTalk is the most constrained at 1,000 records/request; Dynamics 365 DMF offers the most configurability for tuning parallel imports.
- Key limit: Salesforce caps at 150 MB/job and 150M records/24h; SAP IDoc recommends <10 MB per document; NetSuite SOAP maxes at 1,000 records/call with 5-20 concurrent connections; D365 DMF defaults to 8 parallel threads but is configurable.
- Watch out for: SAP IDocs are no longer supported in SAP Cloud ERP (public cloud) starting August 2025 release 2508 — only OData/SOAP/REST APIs remain. [src3]
- Best for: High-volume data migrations (>100K records), scheduled batch imports, initial system loads, and recurring bulk synchronizations between ERPs and external systems.
- Authentication: Each system uses its own auth — Salesforce OAuth 2.0, SAP certificate/SSO, Oracle OAuth 2.0, NetSuite TBA/OAuth 2.0, D365 Microsoft Entra ID.
System Profile
This comparison covers the five most widely adopted ERP bulk import mechanisms. Each system takes a fundamentally different architectural approach: Salesforce uses an asynchronous REST-based job model, SAP uses a document-oriented messaging protocol (IDoc/ALE), Oracle Fusion uses file-based templates processed via ESS jobs, NetSuite uses SOAP web services with governance-controlled concurrency, and Microsoft uses a configurable framework with parallel staging-to-target processing.
| System | Role | API Surface | Bulk Mechanism |
| Salesforce | CRM + Platform | Bulk API 2.0 (HTTPS/CSV) | Async job-based: upload CSV, poll status |
| SAP S/4HANA | ERP (Finance, SCM, HR) | IDoc/ALE (RFC/tRFC) | Message-based: packet processing, parallel IDocs |
| Oracle ERP Cloud | ERP (Finance, Procurement, SCM) | FBDI (File upload + ESS job) | File-based: Excel template to CSV, upload, schedule |
| Oracle NetSuite | ERP (Finance, CRM, Commerce) | SuiteTalk SOAP / CSV Import | SOAP lists (1K/call) or UI CSV import (25K/file) |
| Dynamics 365 F&O | ERP (Finance, SCM) | DMF/DIXF (OData + staging) | Framework-based: configurable threads, staging tables |
API Surfaces & Capabilities
| Bulk Mechanism | Protocol | Best For | Max Records/Request | File/Payload Limit | Async? | Auth |
| SF Bulk API 2.0 | HTTPS/CSV | ETL, data migration, >2K records | 150M records/24h | 150 MB per job | Yes | OAuth 2.0 |
| SAP IDoc/ALE | RFC/tRFC | Master data distribution, EDI, batch posting | Configurable packet (50-100) | <10 MB recommended | Yes (tRFC) | Certificate/SSO |
| Oracle FBDI | File upload + REST | Initial loads, module-specific imports | Module-dependent (500-10K) | Excel template (varies) | Yes (ESS job) | OAuth 2.0 |
| NetSuite SuiteTalk | SOAP/XML | Bulk operations <25K records | 1,000 per SOAP call | 50 MB (CSV) | Optional | TBA / OAuth 2.0 |
| D365 DMF | OData + staging | Data migration, recurring imports | Configurable threshold | 256 MB - 5 GB | Yes (batch) | Microsoft Entra ID |
Rate Limits & Quotas
Per-Request Limits
| System | Limit Type | Value | Notes |
| Salesforce | Max file per job | 150 MB | Split larger datasets across multiple jobs [src1] |
| Salesforce | Max query result | 15 GB (15 files x 1 GB) | Bulk query only [src2] |
| SAP | Max IDoc size (recommended) | 10 MB | Larger IDocs degrade performance [src3] |
| SAP | Packet size (configurable) | Default 1, recommend 50-100 | Partner profile setting |
| Oracle FBDI | Lines per upload (procurement) | 500 draft / 10,000 approved | Module-specific limits [src4] |
| NetSuite | Records per SOAP call | 1,000 | addList/updateList operations [src5] |
| NetSuite | Records per CSV file | 25,000 or 50 MB | Whichever limit is reached first |
| D365 DMF | Export file size | 256 MB (default), 5 GB (configurable) | Requires AzureStorageServiceVersion update [src7] |
| D365 | OData batch | 5,000 operations per batch | Avoids request count limit [src6] |
Rolling / Daily Limits
| System | Limit Type | Value | Window |
| Salesforce | Records imported | 150,000,000 | 24h rolling [src1] |
| Salesforce | Bulk API batches | 15,000 | 24h rolling [src1] |
| SAP | API calls | No hard daily cap | Throttled by dialog work processes |
| Oracle FBDI | ESS job submissions | No documented daily cap | Queue-based, limited by ESS slots |
| NetSuite | API calls | Tier-dependent | 60-second + 24-hour rolling windows [src5] |
| D365 | Requests per user | 6,000 | 5-minute sliding window [src6] |
| D365 | Execution time per user | 1,200 seconds | 5-minute sliding window [src6] |
Concurrency Limits
| System | Concurrent Limit | Details |
| Salesforce | Org-level (edition-dependent) | 100 Bulk API 2.0 jobs queued, 5 batches processing [src1] |
| SAP | Dialog work processes | Shared with all RFC/tRFC activity; configurable per system |
| Oracle FBDI | ESS concurrent slots | Shared with all scheduled processes in the pod |
| NetSuite | 5-20 base (tier-dependent) | +10 per SuiteCloud Plus license; shared across REST/SOAP/RESTlet [src5] |
| D365 | 52 concurrent requests per user | Per user, per app ID, per web server [src6] |
Authentication
| System | Flow | Use When | Notes |
| Salesforce | OAuth 2.0 JWT Bearer | Server-to-server bulk jobs | Recommended for unattended integrations [src1] |
| SAP | X.509 Certificate | System-to-system IDoc exchange | Configured in partner profiles + SM59 RFC destinations |
| Oracle | OAuth 2.0 + IDCS | FBDI REST upload | Token via Oracle IDCS or OCI IAM |
| NetSuite | Token-Based Auth (TBA) | SuiteTalk SOAP calls | Consumer key + token pair [src5] |
| D365 | Microsoft Entra ID (OAuth 2.0) | All API + DMF access | App registration with client credentials [src6] |
Authentication Gotchas
- SAP IDoc partner profile misconfiguration is the #1 cause of "IDoc stuck in status 30" errors — verify RFC destination connection test first [src3]
- NetSuite TBA tokens expire if the role is inactivated or the employee record is modified — use a dedicated integration role [src5]
- D365 user-based throttling tracks by user object ID + app client ID combination — one service account can still hit limits across multiple integrations [src6]
Constraints
- SAP IDocs are NOT available in SAP S/4HANA Public Cloud (Cloud ERP) starting release 2508 (August 2025) — only OData, SOAP, and REST APIs are supported [src3]
- Salesforce Bulk API 2.0 does not support real-time operations — minimum latency is seconds to minutes depending on queue depth [src1]
- Oracle FBDI requires module-specific Excel templates — you cannot use arbitrary CSV formats [src4]
- NetSuite REST API can only create/update one record per request — use SuiteTalk SOAP for bulk (1,000/call) or CSV import (25,000/file) [src5]
- D365 DMF is exempt from service protection API limits, but OData-based integrations are NOT exempt [src6]
- NetSuite concurrency is shared across ALL integration types (SOAP, REST, RESTlet) — a single high-volume integration can starve others [src5]
- D365 DMF requires batch mode for parallel processing — running without batch uses a single thread [src7]
Integration Pattern Decision Tree
START -- User needs to bulk import data into an ERP
|
+-- Which ERP system?
| +-- Salesforce
| | +-- Records > 2,000? --> Bulk API 2.0 (CSV upload, async)
| | +-- Records < 2,000? --> REST API (composite, sync)
| | +-- Migration > 10M records? --> Bulk API 2.0 with job chunking (150 MB/job)
| +-- SAP S/4HANA
| | +-- On-premise / Private Cloud?
| | | +-- Structured EDI/master data --> IDoc/ALE (packet size 50-100)
| | | +-- Custom data --> BAPI via RFC
| | | +-- Modern API --> OData with $batch
| | +-- Public Cloud (Cloud ERP)?
| | +-- IDocs NOT available --> OData or SOAP APIs only
| +-- Oracle ERP Cloud (Fusion)
| | +-- Standard import process exists? --> FBDI
| | +-- Custom data entity? --> REST API
| | +-- HCM data? --> HCM Data Loader (HDL)
| +-- NetSuite
| | +-- Volume < 25K records? --> CSV Import or SuiteTalk SOAP (1K/call)
| | +-- Volume > 25K records? --> Split into 25K chunks
| +-- Dynamics 365 F&O
| +-- Data migration? --> DMF with batch mode, 8-16 threads
| +-- Recurring? --> Recurring integrations (exempt from API limits)
| +-- Ad-hoc API? --> OData $batch (max 5,000 ops)
+-- Cross-system bulk transfer?
+-- Source ERP --> flat file/CSV --> Target ERP bulk import
+-- Or use middleware (MuleSoft, Boomi, Workato)
Quick Reference
| Capability | Salesforce Bulk API 2.0 | SAP IDoc/ALE | Oracle FBDI | NetSuite SuiteTalk | D365 DMF |
| Max records/request | 150M/24h (150 MB/job) | Configurable packet (50-100) | Module-dependent (500-10K) | 1,000/SOAP call | Configurable threshold |
| Max file/payload | 150 MB per job | <10 MB recommended | Excel template (varies) | 50 MB (CSV) | 256 MB - 5 GB |
| Async processing | Yes (poll status) | Yes (tRFC, batch) | Yes (ESS job) | Optional (SuiteScript) | Yes (batch framework) |
| File format | CSV only | XML (IDoc segments) | CSV from Excel template | CSV or XML (SOAP) | CSV, XML, Excel |
| Parallel processing | Platform-managed | Configurable (packets) | ESS slot-limited | Concurrency-governed (5-20) | Configurable threads (8-16+) |
| Error handling | Per-record results | IDoc status (WE02/WE05) | ESS job log + row-level | Per-record in response | Staging table error log |
| Partial success | Yes (per-record) | Yes (per-IDoc) | Yes (row-level) | Yes (per-record) | Yes (per-record) |
| Rollback support | No (per-record commit) | Transaction-level (packet) | No (row-level commit) | No (per-record commit) | Transaction-level (configurable) |
| Cloud availability | All editions | On-prem + Private Cloud ONLY | All Fusion Cloud editions | All NetSuite editions | Cloud (F&O Online) |
| Maturity | Very high (GA since 2018) | Very high (30+ years) | High (GA since Fusion launch) | Moderate (SOAP-era design) | High (GA since D365 launch) |
| Learning curve | Low (REST + CSV) | High (ALE config) | Medium (templates, ESS) | Medium (SOAP, governance) | Medium (entity config, batch) |
Error Handling & Failure Points
Common Error Codes
| System | Error Code/Status | Meaning | Resolution |
| Salesforce | INVALID_BATCH | Job data could not be parsed | Verify CSV encoding (UTF-8, no BOM) [src1] |
| Salesforce | Job state Failed | Entire job failed (system error) | Check job info endpoint; retry with backoff [src2] |
| SAP | IDoc status 51 | Application error during inbound processing | Check WE02/WE05; fix data and reprocess via BD87 [src3] |
| SAP | IDoc status 30 | Ready to dispatch (stuck) | RFC destination down — test SM59 connection |
| Oracle FBDI | ESS job Error | Import process failed | Check ESS job output file for row-level errors [src4] |
| NetSuite | SSS_REQUEST_LIMIT_EXCEEDED | Concurrency limit hit (SOAP) | Implement exponential backoff [src5] |
| NetSuite | HTTP 429 | Rate limit exceeded (REST) | Back off; check governanceLimits endpoint [src5] |
| D365 | HTTP 429 | Service protection limit exceeded | Read Retry-After header; implement backoff [src6] |
Failure Points in Production
- Salesforce CSV encoding: Bulk API 2.0 jobs produce incorrect data with BOM characters or non-UTF-8. Fix:
Always strip BOM and enforce UTF-8 encoding before upload. [src1]
- SAP IDoc packet size = 1: Default processes one IDoc per transaction; 100K+ IDocs exhaust dialog processes. Fix:
Increase packet size to 50-100 in partner profile (WE20) and enable background processing. [src3]
- Oracle FBDI wrong template version: Using a previous release template causes silent column misalignment. Fix:
Re-download templates from target environment before each import cycle. [src4]
- NetSuite concurrency starvation: A single integration consuming all slots blocks everything else. Fix:
Allocate max 10 of 15 slots to any single integration; use governanceLimits endpoint to monitor. [src5]
- D365 DMF single-thread execution: Running without batch mode uses only one thread. Fix:
Always execute in batch mode with dedicated batch group. [src7]
- D365 Excel driver contention: Excel files can fail after 10-minute timeout. Fix:
Convert Excel to CSV before import. [src7]
Anti-Patterns
Wrong: Using NetSuite REST API for bulk operations
// BAD -- REST API processes one record at a time
for (const record of records) {
await fetch(`https://${accountId}.suitetalk.api.netsuite.com/...`, {
method: 'POST', body: JSON.stringify(record)
});
}
// 10,000 records = 10,000 API calls = hits concurrency + rate limits
Correct: Use SuiteTalk SOAP addList for bulk operations
// GOOD -- SOAP addList processes up to 1,000 records per call
const batchSize = 1000;
for (let i = 0; i < records.length; i += batchSize) {
const batch = records.slice(i, i + batchSize);
await soapClient.addList({ record: batch });
}
// 10,000 records = 10 API calls
Wrong: Running D365 DMF imports without batch mode
// BAD -- Direct execution uses single thread
// Data Management > Import > Execute (without batch)
// 100K records processed sequentially = hours
Correct: Execute DMF in batch mode with parallel threads
// GOOD -- Enable batch mode with dedicated batch group
// Import threshold record count: 2,500
// Import task count: 4-8
// 100K records / 4 threads = 4x faster
Wrong: SAP IDoc with default packet size for high-volume loads
// BAD -- Default packet size = 1
// 50,000 IDocs = 50,000 transactions = dialog process exhaustion
Correct: Configure packet processing with appropriate batch size
// GOOD -- Set packet size 50-100 in WE20 partner profile
// 50,000 IDocs / 100 = 500 transactions
// Enable background processing: BD87 batch job
Common Pitfalls
- Salesforce: Not checking per-record results: Bulk API 2.0 jobs can return jobComplete with partial failures. Fix:
Always poll both successfulResults and failedResults endpoints. [src1]
- SAP: Assuming IDoc availability in cloud: Cloud ERP (2508+) dropped IDoc support. Fix:
Audit IDoc interfaces; migrate to OData $batch or SOAP before cloud migration. [src3]
- Oracle FBDI: Skipping validation step: Errors only visible after ESS job execution. Fix:
Pre-validate data against published field requirements before upload. [src4]
- NetSuite: Ignoring governance unit costs: Different operations consume different units. Fix:
Calculate total governance cost before bulk submission; prefer SuiteQL for reads. [src5]
- D365: Not disabling change tracking during migration: Adds overhead to every insert/update. Fix:
Disable change tracking before migration; re-enable after. [src7]
- Cross-system: Assuming same date/time formats: Salesforce UTC, SAP local timezone, NetSuite user preference. Fix:
Normalize all datetime values to UTC/ISO 8601 in integration layer.
Diagnostic Commands
# === Salesforce Bulk API 2.0 ===
# Check job status
curl -H "Authorization: Bearer $SF_TOKEN" \
"https://yourinstance.salesforce.com/services/data/v62.0/jobs/ingest/$JOB_ID"
# Get failed records
curl -H "Authorization: Bearer $SF_TOKEN" \
"https://yourinstance.salesforce.com/services/data/v62.0/jobs/ingest/$JOB_ID/failedResults"
# Check API usage limits
curl -H "Authorization: Bearer $SF_TOKEN" \
"https://yourinstance.salesforce.com/services/data/v62.0/limits"
# === SAP IDoc ===
# Check IDoc status: transaction WE02 or WE05
# Reprocess failed IDocs: transaction BD87
# Test RFC destination: transaction SM59
# === Oracle FBDI ===
# Check ESS job status
curl -H "Authorization: Bearer $OCI_TOKEN" \
"https://instance.fa.ocs.oraclecloud.com/hcmRestApi/resources/.../erpintegrations?finder=ESSJobStatusFinder;requestId=$JOB_ID"
# === NetSuite ===
# Check governance limits
curl -H "Authorization: OAuth ..." \
"https://$ACCOUNT.suitetalk.api.netsuite.com/services/rest/record/v1/metadata-catalog/governanceLimits"
# === D365 F&O ===
# Monitor via LCS or OData
curl -H "Authorization: Bearer $D365_TOKEN" \
"https://instance.operations.dynamics.com/data/DataManagementDefinitionGroups"
Version History & Compatibility
| System | Mechanism | Current Version | Key Change | Status |
| Salesforce | Bulk API 2.0 | v62.0 (Spring '26) | Simplified from 1.0 | Current, GA |
| SAP | IDoc/ALE | S/4HANA 2408 | No major changes on-prem | Current (on-prem) |
| SAP | IDoc/ALE | Cloud ERP 2508 | Removed from public cloud | Sunset (public cloud) |
| Oracle | FBDI | 25C | Template updates per release | Current, GA |
| NetSuite | SuiteTalk SOAP | 2025.1 | Governance model updates | Current, GA |
| D365 F&O | DMF/DIXF | 10.0.39+ | User-based limits removed (10.0.36) | Current, GA |
When to Use / When Not to Use
| Use When | Don't Use When | Use Instead |
| Data migration >10K records into any ERP | Real-time record updates (<1s needed) | System-specific REST/OData API |
| Scheduled daily/weekly batch loads | Event-driven integration (CDC, webhooks) | Platform Events, CDC, Business Events |
| Initial system load during implementation | Interactive user-initiated single-record ops | Standard UI import or REST API |
| Cross-system data sync (nightly) | Sub-second data replication | Change Data Capture or streaming |
| Master data distribution across ERP landscape | Complex multi-step business process orchestration | Middleware workflow engine |
Cross-System Comparison
| Capability | Salesforce Bulk API 2.0 | SAP IDoc/ALE | Oracle FBDI | NetSuite SuiteTalk | D365 DMF |
| Architecture | REST + async job queue | RFC/tRFC message passing | File upload + ESS job | SOAP web services | Staging table + batch |
| Max throughput | 150M records/24h | Limited by dialog processes | Limited by ESS slots | ~25K records/hour | Configurable (threads x records) |
| Developer experience | Excellent (REST, CSV) | Steep (ABAP, ALE config) | Moderate (template-driven) | Moderate (SOAP, governance) | Moderate (entity config, batch) |
| Error granularity | Per-record | Per-IDoc status codes | Row-level in ESS output | Per-record in SOAP response | Per-record in staging table |
| Cloud-native? | Yes | No (sunset in cloud) | Yes | Yes | Yes |
| Format flexibility | CSV only | XML (rigid IDoc segments) | Excel template to CSV | XML or CSV | CSV, XML, Excel |
| Cost model | API allocation (by edition) | Included (on-prem license) | Included (Fusion license) | Governance units + concurrency | Included (F&O license) |
| Monitoring | Job status API | WE02/WE05/SM50 | ESS job console | SuiteScript logs | DMF log + LCS |
| Best for | SaaS integrations, ETL | On-prem ERP-to-ERP, EDI | Oracle ecosystem imports | Mid-market bulk ops | Enterprise data migration |
Important Caveats
- Rate limits and concurrency quotas vary significantly by edition/tier — always verify limits against your specific license agreement
- SAP IDoc sunset in public cloud is the most significant breaking change — organizations planning SAP cloud migration must budget for interface redesign
- Oracle FBDI templates change with each quarterly release — never cache templates across environment updates
- NetSuite's shared concurrency pool means bulk operations directly compete with real-time UI and REST API usage by end users
- D365 service protection limits are resource-based and can vary between environments — Microsoft explicitly states these limits "can change and might vary among environments" [src6]
- All performance numbers represent documented limits, not guaranteed throughput — actual performance depends on data complexity, validations, customizations, and system load
Related Units