SuiteQL Result Limits and Pagination Explained
Understand the 5,000-row runSuiteQL limit, runSuiteQLPaged page sizes, deterministic ordering, governance and the 100,000-row paged-result ceiling.
A SuiteQL query can be correct and still return fewer rows than expected. The execution method—not just the SQL—determines how many results you can retrieve.
For SuiteScript, the first decision is whether to use query.runSuiteQL() or query.runSuiteQLPaged().
The limits at a glance
| Method | Relevant limit |
|---|---|
query.runSuiteQL() |
Up to 5,000 rows |
query.runSuiteQLPaged() |
Page size from 5 to 1,000 rows |
| Paged results | Up to 1,000 pages |
| Paged results without SuiteAnalytics Connect | Up to 100,000 rows in total |
| Governance | 10 units for either execution method |
Oracle’s runSuiteQLPaged() documentation also requires a unique and unambiguous sort order. Without one, records can be duplicated or omitted as the pages are read.
Use runSuiteQL() for bounded results
When the query is guaranteed to return fewer than 5,000 rows, the non-paged method is simple:
const rows = query.runSuiteQL({
query: `
SELECT
customer.id,
customer.entityid
FROM
customer
WHERE
customer.isinactive = ?
ORDER BY
customer.id
`,
params: ['F'],
}).asMappedResults();
Do not silently rely on the limit when processing a table that can grow. Add a selective filter or switch to paging.
Use runSuiteQLPaged() for larger sets
const pagedData = query.runSuiteQLPaged({
query: `
SELECT
transaction.id,
transaction.tranid,
transaction.lastmodifieddate
FROM
transaction
WHERE
transaction.lastmodifieddate >= TO_DATE(?, 'YYYY-MM-DD')
ORDER BY
transaction.lastmodifieddate,
transaction.id
`,
params: [startDate],
pageSize: 1000,
customScriptId: 'custscript_recent_transactions',
});
for (const pageRange of pagedData.pageRanges) {
const page = pagedData.fetch({ index: pageRange.index });
for (const result of page.data.results) {
const row = result.asMap();
processTransaction(row);
}
}
The secondary id sort makes the order deterministic when multiple records share the same modification timestamp.
Why unique ordering matters
This order is not necessarily unique:
ORDER BY transaction.lastmodifieddate
Many transactions can share the same timestamp. Add a stable unique value as the final sort key:
ORDER BY
transaction.lastmodifieddate,
transaction.id
This is especially important for long-running jobs where records might be created or updated while pages are processed.
TOP limits output but is not pagination
SuiteQL supports queries such as:
SELECT TOP 100
customer.id,
customer.entityid
FROM
customer
ORDER BY
customer.id
This is useful for deliberate previews, but it does not provide a cursor for the next 100 rows. Oracle also warns that TOP can affect performance because SuiteQL runs against a virtual schema.
For recurring integrations, filter by an indexed key instead:
WHERE customer.id > ?
ORDER BY customer.id
Store the greatest processed ID and pass it into the next execution. This keyset-style batching avoids repeatedly scanning and discarding earlier rows.
REST SuiteQL uses limit and offset
SuiteTalk REST queries paginate through URL parameters:
POST /services/rest/query/v1/suiteql?limit=1000&offset=2000
Prefer: transient
The request body still contains the SuiteQL query:
{
"q": "SELECT id, entityid FROM customer ORDER BY id"
}
REST offset pagination and N/query paged data are separate APIs. Do not copy the REST limit and offset parameters into runSuiteQLPaged().
Performance and governance
Paging controls memory and response size, but it does not make an expensive query cheap. Keep the workload bounded:
- Select named columns instead of
SELECT *. - Filter on IDs or
lastmodifieddatefor incremental processing. - Avoid unnecessary joins and calculated fields.
- Use a
customScriptIdso NetSuite can identify a problematic query. - Yield or reschedule long processing outside the query loop when the script type requires it.
Choosing the right approach
Use runSuiteQL() when the result is naturally small and bounded. Use runSuiteQLPaged() when the result may exceed 5,000 rows. Use incremental ID or modification-date batches when the dataset can approach 100,000 rows or must be processed reliably over multiple executions.