What Breaks First When API Limits Are Ignored

A company running three integrations concurrently—a nightly ERP sync, a webhook from a payment system, and an external dashboard pulling data every five minutes—doesn't fail gradually. It works perfectly until it crosses a threshold, then every additional API call is rejected with a REQUEST_LIMIT_EXCEEDED code until the daily reset. There's no built-in early warning to prevent this preemptively—only a dashboard you can look at, if someone has built a process to check it.

This type of failure differs from most Salesforce project failures because it's not dependent on bad code or poor design. It's dependent on accumulation: a new integration is always built against the current state, without checking how much of the daily budget is already consumed by existing processes. The result is that the fifth integration "breaks" the four that preceded it, even though none of them changed.

The Practically Relevant Limit Map

Not every Salesforce Limit matters equally for integration planning. The ones that truly dictate architecture are:

Limit TypeWhat It MeasuresWho It Affects First
Daily API RequestsTotal REST/SOAP calls in 24 hoursAny high-frequency synchronous integration
Bulk API BatchesNumber of open/daily batchesNightly batch processes importing historical data
Concurrent Long-Running RequestsCalls running over 20 seconds concurrentlyHeavy reports or complex synchronous Apex
Platform Event DeliveryVolume of events per day per subscriberEvent-Driven architectures between Salesforce and external systems
SOQL Rows per TransactionRows retrieved in a single transaction (50,000)Apex logic running queries inside a loop

This table isn't generic documentation—it's a prioritization. An organization planning a new integration should first examine the first two rows, as these are the ones that actually get blocked in production. Other limits primarily affect performance, not availability.

Request Budget: How to Build It Right

The central tool for preventing blocking isn't reactive monitoring but a predefined budget for each API consumer. The principle: every external system, every Integration User, and every scheduled process receives a defined allocation from the overall quota, not "as much as needed."

Building the budget involves three steps:

  1. Consumer Mapping - A list of every process that calls the API: external integrations, Scheduled Apex, manual Data Loader, BI tools. Each should have a separate Integration User so consumption can be isolated in Event Monitoring.
  2. Load Calculation by Business Volume, Not Assumption - How many records are processed daily, how many calls are required per record (including fetching Related Lists), and what happens during peak times (quarter-end, Black Friday, month-end close).
  3. Reserve Allocation - Don't divide 100% of the quota among existing processes. Keep 15%-20% as a reserve for emergency processes, ad-hoc reports, and maintenance—otherwise, any small addition pushes the organization into overuse.

For those interested in delving deeper into designing the layer that manages this budget at the platform level, read the CRM Architecture Guide, which presents the division between the integration layer and the business layer.

REST vs. Bulk: When the Switch Pays Off

The most common mistake is using the standard REST API for high-volume data traffic, because it's built first and works for a PoC. The problem arises when volume grows: REST counts each request (up to 200 records in Composite) as a separate call against the quota, while Bulk API 2.0 runs batches of up to 10,000 records and is counted at a significantly lower cost per record.

A practical rule of thumb: if a single process updates over approximately 2,000 records in one run, switching to Bulk API almost always pays off—even if it means changing the consumer code to work asynchronously with job status polling instead of an immediate response. The price is higher latency (minutes instead of seconds), so Bulk is not suitable for processes requiring real-time decisions, such as inventory checks before order approval.

Backoff and Retry: Preventing Self-Inflicted Overload

When an API call fails due to a Limit block, the instinctive response of most teams is to try again immediately. This is precisely the behavior that turns a temporary block into a prolonged outage: if ten processes retry at the same moment, they push the system deeper into the block instead of allowing it to recover.

A proper Backoff mechanism requires three components together:

  • Exponential Backoff - The waiting time between retries increases exponentially (e.g., 2, 4, 8, 16 seconds), not linearly.
  • Jitter - A small random addition to the waiting time, so that parallel processes don't retry at the exact same second and create a new wave of load.
  • Circuit Breaker - After a certain number of consecutive failures (e.g., five), the process stops trying completely for a defined period and reports to monitoring, instead of continuing to "knock on the door."

Without a Circuit Breaker, a process running every five minutes and consistently failing will continue to try a hundred times a day and consume quota on failures alone—which is the exact opposite of what the mechanism is meant to prevent. Further details on error handling at the integration level can be found in Salesforce Integration Error Handling.

Scenario: Retail with Three Integration Points

Consider a medium-sized retail chain, about 40 branches, operating Salesforce Service Cloud against a POS system and an ERP system for inventory. Three active integrations: inventory sync every 15 minutes from the ERP (approx. 8,000 SKUs), a webhook from the POS for every failed transaction (approx. 300 per day), and an external Power BI dashboard pulling service data hourly.

The month the chain added a new loyalty program, a fourth integration came online: real-time credit point lookup against Salesforce from every register, adding about 6,000 more calls daily. Within two weeks, inventory syncs started failing around 2-3 PM, peak hours for the registers. The team initially checked the ERP, thinking the problem was there, but the Salesforce log showed REQUEST_LIMIT_EXCEEDED precisely during that window.

The solution wasn't to buy more quota, but to change priorities: credit point lookup transitioned to using Platform Cache for results that don't change frequently, reducing calls by about 70%, and inventory sync moved from REST to Bulk API, running every 30 minutes instead of 15. The result: the same business coverage, about 45% lower quota consumption, and a real reserve for the next growth phase.

Risks and Specific Preventive Actions

RiskHow It Manifests in ProductionPreventive Action
New integration not checked against existing budgetBlocking appears only after Go-LiveRequire a Capacity Review for every new integration before Go-Live
Retry without BackoffTemporary block becomes an hours-long outageExponential Backoff with Jitter and Circuit Breaker in every API consumer
Using REST for large volumesA single process consumes tens of percentages of the daily quotaSwitch to Bulk API above a predefined volume threshold
No separation of Integration UsersCannot determine which integration consumes the quotaDedicated Integration User for each external system, monitored separately
Lack of reserve in the budgetAny small addition pushes into overuseAllocate 15%-20% of the quota as a permanent reserve not allocated to daily processes

Checklist Before Adding a New Integration

  • ☐ Current daily quota consumption is known, by Integration User
  • ☐ Peak volume (not average volume) of the new integration has been assessed
  • ☐ REST vs. Bulk API decided based on volume threshold, not development convenience
  • ☐ Backoff mechanism with Jitter and Circuit Breaker exists in the consumer code
  • ☐ An alert is configured for when daily quota consumption exceeds 70%
  • ☐ Potential use of Platform Cache to reduce repetitive calls has been evaluated
  • ☐ A reserve of 15%-20% of the quota has been set aside and is not pre-allocated
  • ☐ An operational owner who receives alerts, not just a technical log, has been defined

How to Monitor This Continuously

Reliable measurement requires combining three sources: Event Monitoring (or Shield Event Monitoring) for actual API consumption by user, Apex Limits within the code itself (Limits.getLimitApiRequests()) for local runtime checks, and the built-in dashboard under Company Information that displays consumption against quota at the organization level. None of the three is sufficient alone: the first shows trends, the second prevents failure within a single process, and the third serves as a daily snapshot for the operations team.

A metric worth tracking over time isn't just "how much was consumed" but "what is the monthly growth rate in consumption"—because this is what allows predicting when the organization will hit the limit, instead of reacting after the blockage has already occurred. When several systems are interdependent, it's also worth examining the overall integration pattern against Connecting Salesforce to ERP Systems, and the question of implementation—Flow vs. Apex—which also affects call efficiency, in Salesforce Flow or Apex.

Summary

Salesforce API Limits are not a problem to be solved once discovered—they are a variable that must be part of every integration decision from day one. A documented request budget by Integration User, conscious choice between REST and Bulk based on volume, and a Backoff mechanism that prevents self-inflicted overload—these three together distinguish an organization that discovers the problem only when already blocked, from an organization that sees it approaching a month in advance and acts in time.