SuiteQL vs saved search: picking the right NetSuite query tool
Saved searches are NetSuite’s point-and-click reports that anyone with the right role can build, share and schedule. SuiteQL is SQL over the same data, for developers and integrations. Most accounts need both: saved searches for people, SuiteQL for code.
- Updated
- October 5, 2026
- Written by
- Nitya Hoyos
- Covers
- Approach, trade-offs
- Questions
- 3 answered below
(01)The situation
Saved searches are built in the UI and live inside NetSuite: they power dashboards, reminders, scheduled emails, workflow conditions and lists that users filter themselves. Their limits show up in code. Joins are limited to the relationships the search type exposes, aggregating across several record types usually means several searches, and the result columns are defined by the search rather than by the code calling it, so someone editing a saved search in the UI can break an integration that reads it.
SuiteQL is a SQL dialect over NetSuite’s analytics data source. It can join any tables the records catalog exposes, group and aggregate in one query, and lives in the code that uses it, so it is versioned and reviewed with the integration. It runs in SuiteScript through the N/query module, from outside NetSuite through the REST web services SuiteQL endpoint, and through SuiteAnalytics Connect if your account has it. It respects the permissions of the role that runs it.
The learning curve is the schema. SuiteQL uses the analytics table and field names, which are not the labels in the UI and are not always the same as saved search field IDs. Transactions live in one transaction table with lines in transactionline, and many list fields return internal IDs unless you ask for display values with BUILTIN.DF. Teams that start with the Records Catalog (Setup > Records Catalog) and test queries in a small tool or script save a lot of trial and error.
(02)The options
Which approach fits
| Approach | Best for | Trade-off |
|---|---|---|
| Saved search | Reports users read, filter and schedule; dashboard portlets; workflow conditions. | Editable in the UI, so code depending on it can break; limited joins. |
| SuiteQL in SuiteScript (N/query) | Server-side logic, RESTlets and scheduled scripts that need joins or aggregates. | Requires knowing the analytics schema. |
| SuiteQL via REST web services | Integrations and portals reading data from outside NetSuite. | Paged results and account concurrency limits shape how much you can pull at once. |
(03)Example
/**
* @NApiVersion 2.1
*/
define(['N/query'], (query) => {
// Last 30 days of sales orders with the customer's name.
const sql = `
SELECT t.tranid, t.trandate, BUILTIN.DF(t.entity) AS customer, t.foreigntotal
FROM transaction t
WHERE t.type = 'SalesOrd'
AND t.trandate >= SYSDATE - 30
ORDER BY t.trandate DESC`;
const recentOrders = () => {
const paged = query.runSuiteQLPaged({ query: sql, pageSize: 1000 });
const rows = [];
paged.pageRanges.forEach((range) => {
rows.push(...paged.fetch({ index: range.index }).data.asMappedResults());
});
return rows;
};
return { recentOrders };
});(04)Where it goes wrong
The mistakes that cost the most
- 01Integrations that read a saved search by ID break when someone adds a filter or renames a column in the UI. Use SuiteQL in code, or lock the search down.
- 02SuiteQL returns internal IDs for list and record fields; use BUILTIN.DF(field) when you need the display value.
- 03Line-level queries need the main line excluded or included deliberately (transactionline.mainline), or totals are counted twice.
- 04Pulling large result sets in one go hits governance or time limits; use the paged APIs and narrow by date.
(05)Before you build
When not to do this
Do not rewrite working saved searches into SuiteQL for their own sake. If people use a report in the UI, a saved search is the right tool; reach for SuiteQL when code needs the data.
(06)Questions
What is SuiteQL?
SuiteQL is a SQL query language for NetSuite data, based on SQL-92 with some Oracle SQL syntax. It can be run in SuiteScript with the N/query module, through the REST web services SuiteQL endpoint, or through SuiteAnalytics Connect.
Is SuiteQL faster than a saved search?
Often for queries that would otherwise need several saved searches, because one SuiteQL query can join and aggregate across tables. For simple lists, the difference is small; the bigger benefit is that the query lives in versioned code.
Where do I find SuiteQL table and field names?
In the Records Catalog (Setup > Records Catalog), which lists each record’s fields and joins for the analytics data source that SuiteQL reads.
Free checklist