Your integration has been running smoothly for months. Then one Tuesday at 11:47 AM, everything stops. API calls start failing with "REQUEST_LIMIT_EXCEEDED". Your support queue floods with tickets. Users can't access critical data. You've hit your Salesforce API rate limit.
API rate limits exist for good reason. They protect Salesforce's multi-tenant infrastructure from runaway processes and ensure fair resource distribution across all customers. But when your business operations depend on real-time data sync, comprehensive integrations, or high-volume automation, these limits become a constraint you must architect around.
The challenge isn't just avoiding rate limits. It's building integrations that scale efficiently as your business grows, that consume API calls judiciously, and that continue functioning reliably even as data volumes increase.
This guide covers practical strategies for optimizing Salesforce API consumption. You'll learn how organizations reduce API usage by 70% or more through architectural improvements, when to use specific optimization techniques, and how Salesforce integration services can help implement monitoring that prevents limit breaches before they impact operations.
1. Understanding Salesforce API Rate Limits
Salesforce enforces API limits at multiple levels. Understanding these limits is the first step toward optimization.
Daily API Request Limits
Every Salesforce org has a daily API request limit based on edition and license type. The calculation:
Per-License Allocations (as of 2026)
| Edition |
Calls per User per Day |
| Enterprise Edition |
1,000 calls per user license per day |
| Unlimited Edition |
5,000 calls per user license per day |
| Performance Edition |
5,000 calls per user license per day |
| Developer Edition |
15,000 calls total per day (not per user) |
Example Calculation
Concurrent API Request Limits
Beyond daily limits, Salesforce enforces concurrent request limits to prevent any single org from monopolizing server resources:
- Long-running requests (over 20 seconds): Maximum 10 concurrent
- All other requests: Depends on org type, typically 25–100 concurrent
These limits matter for bulk operations and parallel processing scenarios.
API Call Consumption Rules
Not all API operations consume the same quota:
Standard API Calls (count toward limit)
- REST API requests
- SOAP API requests
- Bulk API job creation (not record processing)
- Streaming API channel creation
- Metadata API requests
Operations That Don't Count
- Bulk API record processing (after job creation)
- Apex callouts from triggered execution
- UI-driven actions
- Reports and dashboards
2. Common Scenarios: When Organizations Hit Rate Limits
Understanding how rate limits get exceeded helps identify optimization opportunities.
Scenario 1
E-commerce Integration Hitting Limits by Noon
Situation
An e-commerce platform integrates with Salesforce to sync orders, inventory, and customer data. The integration uses REST API for real-time sync. The org has 50 user licenses (50,000 daily API limit).
What Happened
Result: Integration stopped at 11:47 AM. Orders couldn't be processed. Customer service couldn't access order history.
Root Cause: Inefficient polling consuming 48,000 API calls for status checks that could be eliminated with event-driven architecture.
Scenario 2
Migration Script Exhausting Quota
Situation
A data migration team runs a script to update 200,000 account records with new territory assignments using REST API in a loop.
What Happened
Result: Script fails halfway through
Root Cause: Using REST API for bulk operations. Bulk API would consume approximately 10–20 API calls for the entire operation instead of 200,000.
Scenario 3
Dashboard Refresh Flooding API
Situation
A real-time sales dashboard displays current pipeline data for 200 sales representatives. Each user's dashboard refreshes every 30 seconds.
What Happened
Result: Daily limit exceeded in first hour of business
Root Cause: Aggressive refresh polling instead of Streaming API for real-time updates.
3. What Happens When You Breach Limits
When you exceed API limits, Salesforce responds with:
403
HTTP Status Code: 403 Forbidden
Error Message (JSON)
{
"message": "TooManyRequests: Total number of requests exceeded daily limit.",
"errorCode": "REQUEST_LIMIT_EXCEEDED"
}
Immediate Impact
- All API requests fail until limits reset (midnight Pacific Time)
- Integrations stop functioning
- Automated processes halt
- Users see error messages
- Data sync stops
No Exceptions: Even critical operations fail. Salesforce doesn't distinguish between essential and non-essential API calls when limits are breached.
4. Optimization Strategy 1: Composite API for Multiple Operations
How Composite API Works
The Composite API allows you to execute up to 25 subrequests in a single API call. Instead of making 10 separate calls to create/update/query different records, you bundle them into one composite request.
Traditional Approach — 10 API Calls
// 10 separate API calls
await createAccount(accountData); // Call 1
await createContact(contactData); // Call 2
await createOpportunity(opportunityData); // Call 3
await updateAccount(accountId, updates); // Call 4
await query('SELECT Id FROM Lead'); // Call 5
// ... 5 more calls
Optimized with Composite API — 1 API Call
const compositeRequest = {
allOrNull: false,
compositeRequest: [
{
method: 'POST',
url: '/services/data/v60.0/sobjects/Account',
referenceId: 'newAccount',
body: { Name: 'Acme Corp', Industry: 'Technology' }
},
{
method: 'POST',
url: '/services/data/v60.0/sobjects/Contact',
referenceId: 'newContact',
body: {
FirstName: 'John',
LastName: 'Smith',
AccountId: '@{newAccount.id}' // Reference previous result
}
},
{
method: 'POST',
url: '/services/data/v60.0/sobjects/Opportunity',
referenceId: 'newOpportunity',
body: {
Name: 'New Deal',
AccountId: '@{newAccount.id}',
StageName: 'Prospecting',
CloseDate: '2025-12-31'
}
},
{
method: 'PATCH',
url: '/services/data/v60.0/sobjects/Account/@{newAccount.id}',
referenceId: 'updateAccount',
body: { Description: 'Updated via Composite API' }
},
{
method: 'GET',
url: '/services/data/v60.0/query?q=SELECT+Id+FROM+Lead+LIMIT+10',
referenceId: 'leadQuery'
}
]
};
// Single API call executes all operations
const response = await fetch(
`${instanceUrl}/services/data/v60.0/composite`,
{
method: 'POST',
headers: {
'Authorization': `Bearer ${accessToken}`,
'Content-Type': 'application/json'
},
body: JSON.stringify(compositeRequest)
}
);
Composite API Results
- Creating account with 2 contacts and 1 opportunity: 4 API calls
- Processing 100 records per hour: 400 API calls/hour
- Daily consumption: 9,600 API calls(24 hours)
- Same operation: 1 API call (bundles all 4 operations)
- Processing 100 records per hour: 100 API calls/hour
- Daily consumption: 2,400 API calls
75%
Reduction — Savings: 7,200 API calls per day for multi-step record creation processes.
When to Use Composite API
Ideal For
- Multi-step processes creating related records
- Operations requiring data from previous steps
- Batch operations under 25 subrequests
- Scenarios where transaction consistency matters
Not Ideal For
- Single, simple operations (adds complexity without benefit)
- Operations exceeding 25 subrequests (use Bulk API)
- Long-running operations (Composite has timeout limits)
5. Optimization Strategy 2: Intelligent Caching to Eliminate Redundant Calls
Many integrations repeatedly query the same Salesforce data that changes infrequently. Caching eliminates these redundant API calls.
Implementing a Caching Layer
Many integrations repeatedly query the same Salesforce data that changes infrequently. Caching eliminates these redundant API calls.
Without Caching — Repeated Queries
// Every request queries Salesforce, even for unchanged data
const getProductInfo = async (productId) => {
// This API call happens every time, even if product hasn't changed
const response = await fetch(
`${instanceUrl}/services/data/v60.0/sobjects/Product2/${productId}`,
{ headers: { 'Authorization': `Bearer ${accessToken}` } }
);
return await response.json();
};
// Called 1000 times per hour = 1000 API calls
With Intelligent Caching
const NodeCache = require('node-cache');
const cache = new NodeCache({ stdTTL: 3600 }); // 1 hour TTL
const getProductInfo = async (productId) => {
// Check cache first
const cached = cache.get(`product_${productId}`);
if (cached) {
console.log('Cache hit - no API call needed');
return cached;
}
// Cache miss - query Salesforce
const response = await fetch(
`${instanceUrl}/services/data/v60.0/sobjects/Product2/${productId}`,
{ headers: { 'Authorization': `Bearer ${accessToken}` } }
);
const data = await response.json();
// Store in cache
cache.set(`product_${productId}`, data);
return data;
};
// First call: 1 API call (cache miss)
// Next 999 calls in same hour: 0 API calls (cache hits)
Cache Invalidation Strategy
Caching only works if you invalidate stale data. Combine caching with event-driven updates:
// Subscribe to Product update events
client.subscribe('/data/Product2ChangeEvent', (message) => {
const productId = message.data.payload.Id;
// Invalidate cache when product changes
cache.del(`product_${productId}`);
console.log(`Cache invalidated for product ${productId}`);
});
Caching Results
Scenario: E-commerce Integration — 50,000 product queries per day, products updated weekly.
- 50,000 product queries per day
- All queries hit Salesforce API
- Total: 50,000 API calls
- First query per product per hour: Hits Salesforce
- Subsequent queries: Served from cache
- Cache hit rate: 95%
- Total API calls: 2,500 (50,000 × 5%)
95%
Reduction — Savings: 47,500 API calls per day
What to Cache
Good Caching Candidates
- Product catalogs (change infrequently)
- Price lists (updated on schedule)
- User role mappings (stable)
- Configuration metadata (rarely changes)
- Lookup / picklist values (static)
Poor Caching Candidates
- Real-time inventory (changes constantly)
- Order status (needs immediate updates)
- Financial data (accuracy critical)
- Case / ticket data (time-sensitive)
6. Optimization Strategy 3: Bulk API for Large Data Operations
Bulk API is specifically designed for high-volume operations. It processes thousands or millions of records using minimal API calls.
Understanding Bulk API Efficiency
REST API Approach — 50,000 API Calls
// Updating 50,000 account records with REST API
for (const account of accounts) {
await fetch(
`${instanceUrl}/services/data/v60.0/sobjects/Account/${account.Id}`,
{
method: 'PATCH',
headers: {
'Authorization': `Bearer ${accessToken}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({ Industry: 'Technology' })
}
);
// Each update: 1 API call
}
// Total: 50,000 API calls
Bulk API Approach — Approximately 5 API Calls
// Step 1: Create bulk job (1 API call)
const jobResponse = await fetch(
`${instanceUrl}/services/data/v60.0/jobs/ingest`,
{
method: 'POST',
headers: {
'Authorization': `Bearer ${accessToken}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({ operation: 'update', object: 'Account' })
}
);
const job = await jobResponse.json();
// Step 2: Upload data in CSV format (1 API call)
const csvData = accounts.map(a => `${a.Id},Technology`).join('\n');
const csv = `Id,Industry\n${csvData}`;
await fetch(
`${instanceUrl}/services/data/v60.0/jobs/ingest/${job.id}/batches`,
{
method: 'PUT',
headers: {
'Authorization': `Bearer ${accessToken}`,
'Content-Type': 'text/csv'
},
body: csv
}
);
// Step 3: Close job to start processing (1 API call)
await fetch(
`${instanceUrl}/services/data/v60.0/jobs/ingest/${job.id}`,
{
method: 'PATCH',
headers: {
'Authorization': `Bearer ${accessToken}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({ state: 'UploadComplete' })
}
);
// Step 4-5: Monitor job status (2 API calls)
let jobStatus = await checkJobStatus(job.id);
while (jobStatus.state !== 'JobComplete') {
await sleep(5000);
jobStatus = await checkJobStatus(job.id);
}
// Total: 5 API calls for 50,000 records
Bulk API Results
- Updating 50,000 records with REST API: 50,000 API calls
- Operation time: 6–8 hours
- Risk: Hitting daily limit halfway through
- Same 50,000 records: 5 API calls
- Operation time: 15–30 minutes
- Savings: 49,995 API calls
99.99%
Reduction — Savings: 49,995 API calls
When to Switch to Bulk API
7. Optimization Strategy 4: Query Optimization to Reduce API Calls
Inefficient SOQL queries waste API calls by fetching unnecessary data or making redundant queries. Query optimization can reduce API consumption by 40% or more.
Query Optimization Technique 1: Reduce Query Frequency
Inefficient Pattern — Querying in Loops (1,000 API Calls)
// BAD: Querying inside loop (1000 API calls)
for (const orderId of orderIds) {
const order = await query(
`SELECT Id, Status, Amount FROM Order WHERE Id = '${orderId}'`
);
processOrder(order);
}
// Total: 1000 queries = 1000 API calls
Optimized — Single Query with IN Clause (1 API Call)
// GOOD: Single query with IN clause (1 API call)
const orderIdsString = orderIds.map(id => `'${id}'`).join(',');
const orders = await query(
`SELECT Id, Status, Amount FROM Order WHERE Id IN (${orderIdsString})`
);
orders.forEach(order => processOrder(order));
// Total: 1 query = 1 API call
// Savings: 999 API calls (99.9% reduction)
Query Optimization Technique 2: Select Only Required Fields
Inefficient — All Fields
// Fetching all fields (slower, more data)
const accounts = await query(
'SELECT FIELDS(ALL) FROM Account LIMIT 1000'
);
// Returns 50+ fields per record
Optimized — Specific Fields Only
// Fetch only needed fields
const accounts = await query(
'SELECT Id, Name, Industry FROM Account LIMIT 1000'
);
// Returns only 3 fields per record — faster, less data transfer
// Faster response, less data transfer
// API call count: same, but efficiency improved
Query Optimization Technique 3: Use Query Locator for Large Result Sets
Inefficient — Multiple Queries
javascript
// Fetching 50,000 records in multiple queries
let offset = 0;
const batchSize = 2000;
const allRecords = [];
while (offset < 50000) {
const batch = await query(
`SELECT Id, Name FROM Account LIMIT ${batchSize} OFFSET ${offset}`
);
allRecords.push(...batch);
offset += batchSize;
}
// Total: 25 queries = 25 API calls
Optimized — Query Locator Pattern
javascript
// Use queryMore with locator
let queryResult = await query(
'SELECT Id, Name FROM Account'
);
const allRecords = queryResult.records;
while (!queryResult.done) {
queryResult = await queryMore(queryResult.nextRecordsUrl);
allRecords.push(...queryResult.records);
}
// Same 50,000 records
// Total: Fewer API calls (depends on batch size)
// More efficient, handles governor limits better
Scenario: Processing Daily Orders
An integration processes 5,000 orders per day, each requiring account and contact information.
- Query order: 1 call
- Query account: 1 call
- Query contact: 1 call
- 3 calls per order
- Daily total: 15,000 API calls
- Single query with relationships
SELECT Id, Status, Account.Name, Contact.Email FROM Order WHERE ...
- Batch 200 orders per query
- Queries needed: 25 (5,000 ÷ 200)
- Daily total: 25 API calls
99.8%
Reduction — Savings: 14,975 API calls per day
8. Monitoring and Alerting Setup
Proactive monitoring prevents rate limit breaches before they impact operations.
Implement API Limit Monitoring
// Check current API usage
const checkAPILimits = async () => {
const response = await fetch(
`${instanceUrl}/services/data/v60.0/limits`,
{ headers: { 'Authorization': `Bearer ${accessToken}` } }
);
const limits = await response.json();
const dailyLimit = limits.DailyApiRequests.Max;
const dailyUsed = limits.DailyApiRequests.Remaining;
const percentUsed = ((dailyLimit - dailyUsed) / dailyLimit) * 100;
console.log(`API Usage: ${percentUsed.toFixed(1)}%`);
console.log(`Remaining: ${dailyUsed.toLocaleString()} of ${dailyLimit.toLocaleString()}`);
if (percentUsed > 80) {
sendAlert({
severity: 'WARNING',
message: `API usage at ${percentUsed.toFixed(1)}%`,
remaining: dailyUsed
});
}
if (percentUsed > 95) {
sendAlert({
severity: 'CRITICAL',
message: `API limit nearly exhausted: ${percentUsed.toFixed(1)}%`,
remaining: dailyUsed
});
}
return { limit: dailyLimit, used: dailyLimit - dailyUsed, remaining: dailyUsed, percentUsed };
};
// Monitor every 15 minutes
setInterval(checkAPILimits, 15 * 60 * 1000);
Dashboard Metrics to Track
Essential Metrics
- Current API usage (percentage of daily limit)
- API calls per hour (trend analysis)
- API calls by integration/process
- Peak usage times (capacity planning)
- Cache hit rate (caching effectiveness)
- Failed requests due to limits
Alert Thresholds
- 70% usage: Information alert
- 80% usage: Warning alert
- 90% usage: Critical alert
- 95% usage: Emergency alert (throttle non-critical processes)
9. Rate Limit Calculator: Predicting API Consumption
Before deploying integrations, estimate API consumption to avoid surprises.
Rate Limit Calculation Formula
const calculateDailyAPIConsumption = (config) => {
const {
recordsPerDay, // How many records processed daily
apiCallsPerRecord, // API calls needed per record
batchSize, // Records processed per batch (if batching)
cacheHitRate, // Percentage of requests served from cache
compositeUsage // Are you using Composite API?
} = config;
let apiCallsNeeded;
if (compositeUsage) {
apiCallsNeeded = Math.ceil(recordsPerDay / 25);
} else if (batchSize > 1) {
apiCallsNeeded = Math.ceil(recordsPerDay / batchSize) * apiCallsPerRecord;
} else {
apiCallsNeeded = recordsPerDay * apiCallsPerRecord;
}
// Apply cache effectiveness
const effectiveAPICalls = apiCallsNeeded * (1 - cacheHitRate);
return Math.ceil(effectiveAPICalls);
};
// Example calculation
const estimate = calculateDailyAPIConsumption({
recordsPerDay: 10000,
apiCallsPerRecord: 3,
batchSize: 1,
cacheHitRate: 0,
compositeUsage: false
});
console.log(`Estimated daily API calls: ${estimate.toLocaleString()}`);
// Output: Estimated daily API calls: 30,000
Optimization Impact Calculator
const compareOptimizations = (baseline, optimized) => {
const savings = baseline - optimized;
const percentReduction = (savings / baseline) * 100;
console.log(`Baseline: ${baseline.toLocaleString()} calls/day`);
console.log(`Optimized: ${optimized.toLocaleString()} calls/day`);
console.log(`Savings: ${savings.toLocaleString()} calls/day`);
console.log(`Reduction: ${percentReduction.toFixed(1)}%`);
return { savings, percentReduction };
};
// Example: E-commerce integration optimization
compareOptimizations(150000, 45000);
// Baseline: 150,000 calls/day
// Optimized: 45,000 calls/day
// Savings: 105,000 calls/day
// Reduction: 70.0%
10. Planning for Scale: Long-Term API Optimization
As your Salesforce usage grows, API optimization becomes an ongoing discipline rather than a one-time fix.
Scaling Checklist
- Event-driven architecture for real-time updates (eliminates polling)
- Bulk API for all operations over 2,000 records
- Composite API for multi-step processes
- Caching layer for frequently accessed static data
- Query optimization (specific fields, batch fetching, relationship queries)
Monitoring Infrastructure
- Real-time API usage tracking
- Automated alerts at 80% and 90% thresholds
- Per-integration consumption tracking
- Peak usage analysis
- Historical trend analysis
- Regular API consumption audits (monthly)
- Rate limit capacity planning for growth
- Integration code reviews focusing on API efficiency
- Load testing before deploying new integrations
- Documentation of API consumption by process
- Non-critical process throttling playbook
- API limit breach response plan
- Stakeholder communication templates
- Additional API capacity procurement process
Salesforce API rate limits don't have to constrain your integration architecture. With the right optimization strategies, organizations routinely reduce API consumption by 70% or more while improving performance and reliability.
The Key Optimization Strategies
Composite API bundles multiple operations into single calls, reducing consumption by 75–90% for multi-step processes.
Intelligent caching eliminates redundant queries for static or slowly changing data, often achieving 90%+ cache hit rates.
Bulk API migration transforms record-by-record operations consuming thousands of API calls into batch jobs using fewer than 10 calls.
Query optimization reduces unnecessary queries and data transfer, cutting API consumption by 40–99% depending on the scenario.
Combined with proactive monitoring and rate limit planning, these strategies ensure your Salesforce integrations scale sustainably as your business grows.
Need help optimizing your Salesforce API consumption? Our Salesforce integration services team analyzes integration patterns, identifies optimization opportunities, and implements efficient architectures that maximize API efficiency.