Skip to content
Back to Blog
Integration

Composite and GraphQL API: Cutting Salesforce API Calls

Sep 2, 2026
SCSunny Chauhan
Composite and GraphQL API: Cutting Salesforce API Calls

Salesforce has four ways to send several operations in one HTTP request, and they do not all save you API calls. The composite resource counts the entire series as a single call. sObject Collections counts the entire request as a single call. Composite batch counts every subrequest separately.

That last one is the reason teams add batching, watch their API consumption stay flat, and conclude the limits are broken. They are not. /composite/batch was built for convenience, not for allocation.

How each endpoint counts

EndpointMax per requestCounts as
/composite25 subrequests, of which up to 5 may be sObject Collections or query operationsOne call
/composite/sobjects (sObject Collections)200 recordsOne call
/composite/graph500 nodes per graph, 75 graphs per payloadSee below
/composite/batch25 subrequestsEach subrequest counts

Salesforce's wording is unambiguous in both directions. For the composite resource: "The entire series of requests counts as a single call toward your API limits." For sObject Collections: "The entire request counts as a single call toward your API limits." For composite batch: "Each subrequest counts against rate limits."

If reducing API consumption is the goal, /composite and sObject Collections are the tools. Batch is not.

What each one is actually for

/composite, when steps depend on each other

Up to 25 subrequests, with up to 5 of them sObject Collections or query operations including Query and QueryAll.

Two properties make it more than a bundle. Subrequests can share reference IDs, so a later subrequest uses the ID of a record an earlier one created without a round trip to find out what it was. And an allOrNone flag enforces a transaction across the whole request, rolling everything back if any subrequest fails.

That combination covers the common case that otherwise takes four calls and a cleanup path: create an Account, create a Contact against it, create an Opportunity, and have all three vanish together if the third fails.

One limit that bites on read-heavy requests. Once a total of 2,000 records has been fetched across subrequests, the remaining queries return only the first records of their result sets, along with query locator URLs for the rest. The request does not fail, it quietly gives you less than you asked for, so check for locators rather than trusting the record count.

sObject Collections, for many records of the same shape

Up to 200 records in one request, one API call. allOrNone defaults to false, meaning failures are reported per record and the successes stay committed. Set it to true when partial success is worse than no success.

This is the right tool between "a handful of records" and "a bulk job". Below 200 records, sObject Collections beats Bulk API on latency and simplicity. Above it, you are looping, and Bulk API 2.0 is the better shape.

/composite/graph, for scale beyond 25

Composite Graph raises the subrequest ceiling substantially, at the cost of a more structured payload.

Composite Graph limitValue
Max nodes in one graph500
Max graphs in one payload75
Max graph depth15
Max different node types in one payload15
Max graph failures in one request14

Node types differ by API version, HTTP method or object type. Exceed 14 graph failures and processing halts, with the remaining graphs marked PROCESSING_HALTED.

The useful property is that each graph succeeds or fails independently. One failing graph does not take down the other 74, which makes it the right structure for a batch of unrelated record trees where you want partial progress rather than an all-or-nothing outcome.

/composite/batch, for convenience only

25 independent subrequests. They cannot pass information between them, and a failure does not roll back commits made by earlier subrequests. Every subrequest counts against rate limits.

Use it to reduce network round trips when the operations genuinely have nothing to do with each other. Do not use it to reduce API consumption, because it does not.

Where GraphQL fits

Salesforce's GraphQL API uses the same API limits as other Connect API limits. Each query can contain up to 10 subqueries, and each subquery counts as one request for rate limiting.

So GraphQL is not an allocation optimisation either. What it does is let a client ask for exactly the fields it needs across related objects in one round trip, which reduces over-fetching and the number of endpoints a front end has to know about. That is a real benefit for a user interface. It is not the answer to an API limit problem.

GoalReach for
Fewer API calls against the allocation/composite or sObject Collections
Transactional multi-object writes/composite with allOrNone
Many independent record trees, partial progress acceptable/composite/graph
Fewer round trips, allocation irrelevant/composite/batch
Precise field selection for a UIGraphQL
Very large volumesBulk API 2.0

The decision in one pass

Start from what is scarce. If the API allocation is what you are short of, the only endpoints that help are /composite, sObject Collections and Bulk API. If latency is what you are short of, batching of any kind helps, including the ones that do not save calls.

Most orgs that hit an API ceiling get there through per-record REST calls in a loop. Replacing that loop with sObject Collections is usually a hundredfold reduction for an afternoon of work, and it is worth doing before anyone prices an add-on. For how the allocation is calculated in the first place, see our guide to Salesforce API rate limits.

Frequently Asked Questions

Does a composite request count as one API call?

The composite resource does. Salesforce states that the entire series of requests counts as a single call toward your API limits. Composite batch does not: each subrequest there counts against rate limits individually.

What is the difference between composite and composite batch?

Composite subrequests can share reference IDs and can be made transactional with allOrNone, and the whole request counts as one API call. Composite batch subrequests are independent, cannot pass information between them, are not rolled back on failure, and each one counts against rate limits.

How many records can sObject Collections handle?

Up to 200 records in a single request, counting as one API call. The allOrNone parameter defaults to false, so by default failures are reported per record and successful records stay committed.

How many subrequests can a composite request contain?

25, of which up to 5 may be sObject Collections or query operations including Query and QueryAll. Composite Graph raises this considerably, allowing 500 nodes per graph and up to 75 graphs per payload.

Does the Salesforce GraphQL API reduce API calls?

No. GraphQL API uses the same API limits as other Connect API limits, and each of the up to 10 subqueries in a query counts as one request for rate limiting. It reduces over-fetching and round trips, not allocation consumption.

Why does my composite request return fewer records than expected?

Once 2,000 records have been fetched across the subrequests, the remaining queries return only the first records of their result sets plus query locator URLs for the rest. The request succeeds, so the shortfall is silent unless you check for locators.

What happens when a composite graph fails?

Each graph succeeds or fails independently, so one failure does not affect the others. If more than 14 graphs fail within one request, processing halts and the remaining graphs are marked PROCESSING_HALTED.

Sources

  1. Salesforce Developers, REST API Developer Guide, Composite resources: subrequest limits, reference IDs, allOrNone, the 2,000 record query locator behaviour, and the single-call statement. 2/ Salesforce Developers, Composite Batch: independence of subrequests and per-subrequest rate limit counting. 3/ Salesforce Developers, sObject Collections: 200 record limit, single-call statement, allOrNone default. 4/ Salesforce Developers, Composite Graph Limits: nodes, graphs, depth, node types, failure ceiling. 5/ Salesforce Developers, GraphQL API, API Request Limits and Query Limitations. Verified 2 September 2026.

All Blogs