Use pagination to access all GraphQL query results
Skedulo GraphQL provides multiple ways to control the number of results returned in queries. You can access additional data by using pagination.
Using the limit
parameter
The limit
parameter allows you to request up to 10,000 top-level records, with dynamic limits applied based on query complexity to protect system performance.
Dynamic query limits: The maximum value for the limit
parameter is calculated dynamically based on query complexity to protect system performance:
- Default: 200 if not specified
- Header: The calculated limit is returned in the
X-Skedulo-Dynamic-Query-Limit
response header
Subquery limits (for HasMany relationships when using limit
):
- Maximum: 2000
- Default: 20
- Automatic: When using top-level
limit
, all HasMany relationships automatically have alimit
parameter applied (defaults to 20 if not specified) - No pagination: Unlike top-level queries, subqueries on HasMany relationships do not support pagination. Refer to “Subquery Limits and Pagination” section below for more detail.
Error Handling
- If a query exceeds the dynamic query limit, a
query_complexity_limit_exceeded
error is returned
It is recommended that you explicitly specify the sorting direction of the orderBy
parameter/s by using either ASC
for ascending order of results or DESC
for descending order, for example: orderBy: Start DESC, UID ASC
. To use pagination reliably, you should ensure that your query includes an orderBy: UID
parameter so that the result set is stable. In most cases, the sort order direction of the UID is not relevant.
Subquery limits and pagination
Unlike top-level queries, subqueries on HasMany relationships do not support pagination. This means you must carefully consider the limit
parameter for subqueries to ensure you retrieve all the data you need. If you expect many records to be returned by the subquery, consider implementing an independent query for that data.
Guidelines for setting subquery limits
- Understand your data: Analyze your data to understand the typical number of related records
- Use filters: Apply filters to subqueries to reduce the number of records returned
- Set realistic limits: Choose a limit that covers the maximum number of records you expect, but not so high that it significantly impacts the top-level dynamic query limit
- Consider data growth: Account for potential data growth when setting limits
Example: Balancing top-level and subquery limits
{
jobs(limit: 800) {
edges {
node {
UID
Name
JobStatus
JobAllocations(limit: 15, filter: "Status != 'Deleted'") {
UID
Status
}
JobOffers(limit: 8) {
UID
Status
}
}
}
}
}
In this example:
- The top-level query requests up to 800 jobs
- Each job can have up to 15 JobAllocations (no pagination available)
- Each job can have up to 8 JobOffers (no pagination available)
- If a job has more than 15 allocations or 8 offers, the excess records will not be returned
Fetching more related records
If you need more records than the subquery limit allows, consider these approaches:
- Increase the subquery limit (up to the maximum of 2000)
- Use separate queries to fetch related data
- Apply filters to reduce the result set
- Restructure your query to fetch data at the top level instead
Pagination support
Relay cursor pagination
Skedulo Lens GraphQL pagination support uses the Relay Cursor Connections Specification.
For example, the following query for jobs
returns a node
for each job consisting of the UID
and Name
along with an opaque cursor.
{
jobs(orderBy: "UID") {
edges {
cursor
node {
UID
Name
}
}
pageInfo {
hasNextPage
}
}
}
This query would return these results (some data omitted for simplicity):
{
"data": {
"jobs": {
"edges": [
{
"cursor": "MQ==",
"node": {
"UID": "a0E6F00001dWnbrUAC",
"Name": "JOB-0033"
}
},
{
"cursor": "Mg==",
"node": {
"UID": "a0E6F00001dWnbhUAC",
"Name": "JOB-0032"
}
}
],
"pageInfo": {
"hasNextPage": true
}
}
}
}
Note that this fetches each entry with a cursor
. The last entry pageInfo
indicates that there is more data to be fetched. This can be done by supplying the cursor of the last item as an argument to the jobs
query.
For example:
{
jobs(after: "Mg==", orderBy: "UID") {
edges {
cursor
node {
UID
Name
}
}
pageInfo {
hasNextPage
}
}
}
Would give the result:
{
"data": {
"jobs": {
"edges": [
{
"cursor": "Mw==",
"node": {
"UID": "a0E6F00001BiaRWUAZ",
"Name": "JOB-0007"
}
},
{
"cursor": "NA==",
"node": {
"UID": "a0E6F00001BiaRbUAJ",
"Name": "JOB-0008"
}
}
],
"pageInfo": {
"hasNextPage": false
}
}
}
}
You can also limit the number of items returned in the query using the limit
parameter to the “jobs” query.
Example with limit
parameter
{
jobs(limit: 1200, orderBy: "UID") {
edges {
cursor
node {
UID
Name
JobAllocations(limit: 25) {
UID
Status
}
}
}
pageInfo {
hasNextPage
}
}
}
This query will fetch up to 1,200 job records, with each job record limited to a maximum of 25 JobAllocation records. Note that the JobAllocations subquery does not support pagination, so you must select an appropriate limit that covers all the records you need.
See the Relay Cursor Connections Specification for full details of the supported operations.
Start and offset pagination
In addition to the cursor-based paging, Skedulo’s GraphQL implementation also supports using offsets to page results. This can be useful when you want to show pagination controls that allow you to jump ahead in a number of pages, by allowing you to divide into multiples and have the query fetch that many results and render them. To do this we use the offset
parameter to indicate which record the pages should be fetched from and the limit
parameter to indicate the number of records to fetch, for example:
query {
jobs(limit: 3, offset: 0, orderBy: "UID") {
edges {
offset
node {
UID
Name
Description
JobStatus
}
}
}
}
Returns the result:
{
"data": {
"jobs": {
"edges": [
{
"offset": 0,
"node": {
"UID": "0014151a-404c-43bd-ab69-444cf0531e93",
"Name": "JOB-10",
"Description": "Stuff 10",
"JobStatus": "Queued"
}
},
{
"offset": 1,
"node": {
"UID": "0014daaf-ea46-48f3-be2b-13045a953307",
"Name": "JOB-11",
"Description": "Stuff 11",
"JobStatus": "Queued"
}
},
...
]
}
}
Salesforce pagination limitation
Platform-specific limitation
This limitation only applies to Skedulo on Salesforce. The Skedulo Pulse Platform does not have this restriction.Salesforce imposes strict pagination limits that affect how you can access large datasets:
- Maximum offset: 2,000 records from the beginning of the result set
- Maximum total records: 2,000 records when using pagination (cursor or offset-based)
These limitations apply to both cursor-based and offset-based pagination methods.
Example scenarios
Scenario 1: Exceeding the offset limit
# Query 1: Fetch initial results
{
jobs(limit: 10000, orderBy: "UID") {
edges {
cursor
node {
UID
Name
}
}
pageInfo {
hasNextPage
}
}
}
This query returns 10,000 records with a cursor at position 10,000.
# Query 2: Attempt to continue pagination
{
jobs(limit: 500, orderBy: "UID", after: "MTAwMDA=") {
edges {
cursor
node {
UID
Name
}
}
pageInfo {
hasNextPage
}
}
}
Result: Query 2 fails because it attempts to access records at offset 10,000, which exceeds Salesforce’s 2,000 record limit.
Scenario 2: Exceeding the total record limit
{
jobs(limit: 3000, orderBy: "UID", after: "NTAw") {
edges {
cursor
node {
UID
Name
}
}
pageInfo {
hasNextPage
}
}
}
Result: This query returns only 2,000 records (not the requested 3,000) because Salesforce limits the total number of records when using pagination.
Workarounds for large datasets
When working with datasets larger than 2,000 records on Salesforce:
- Use filters to reduce the result set size
- Implement data partitioning by date ranges, UID or other criteria
- Use multiple queries with different filter conditions
- Consider data export for bulk operations
Alternative approach
When not using pagination (noafter
or offset
parameters), you can still fetch up to 10,000 records in a single query as detailed in the GraphQL query limits page.
Feedback
Was this page helpful?