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-Limitresponse header
Subquery limits (for HasMany relationships when using limit):
- Maximum: 2000
- Default: 20
- Automatic: When using top-level
limit, all HasMany relationships automatically have alimitparameter 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_exceedederror 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?