Tips to Optimize Performance

This content is intended to help administrators improve the performance of their NetSuite application and address performance issues that their NetSuite users may experience.

Optimizing Script Architecture and Code

Use SuiteScript 2.1

For the latest changes and improvements, use SuiteScript 2.1 instead of an earlier SuiteScript version for your scripts.

Avoid Slow I/O

When you develop SuiteScripts that interact with the NetSuite application UI, such as user event scripts and client scripts, it is imporant to minimize the use of I/O operations. Slow I/O may significantly impact the responsiveness of your application and may lead to longer page load times for users.

Examples of slow I/O include:

  • Database queries that retrieve large amounts of data

  • Loading files from the File Cabinet

  • Requests to external applications or web services

  • Updating related records within a script

Best Practices:

  • Avoid requesting large amounts of data to be returned from the database to the UI. Instead, calculate values within the script or use cached data if available.

  • Use asynchronous, non-interactive scripts, such as scheduled scripts or map/reduce scripts, to process slow I/O operations.

  • Optimize queries to ensure they return only the data needed for the current operation.

  • Use the N/cache module to cache data that is used multiple times within a script.

Avoid Synchronous Re-edits

When you develop user event scripts, avoid synchronously editing the same record within the script. Do not reload or edit the same record synchronously in the beforeSubmit event. The record is already loaded and available for modification in this context. Attempting to reload the record in beforeSubmit will result in a "Record has been changed" error.

If you need to update the record after it has been saved, use asynchronous processing methods:

  • Where possible, set field values directly on the record in the beforeSubmit event.

  • Use scheduled scripts or map/reduce scripts to avoid errors, long loading times, or blocking user actions.

  • While you may edit the record in the afterSubmit event, you should offload any additional processing to asynchronous scripts instead to maintain optimal performance and user experience.

Use a Single Synchronous Entry Point

Deploy only one user event script and one client script for each record or transaction type. Adding multiple synchronous scripts may slow page-load time.

Best Practices:

  • Merge logic into one file where possible. Keep all synchronous work in a single script file. Break out tasks into helper modules and call them from your main entry point.

  • Keep the entry point light. Offload the most resource-intensive tasks to a scheduled script, map/reduce script, or RESTlet.

  • Review deployments regularly. If you see more than one synchronous script on the same record, consolidate them to reduce initialization overhead and simplify debugging.

A single entry point ensures predictable execution order, minimizes record reloads, and keeps governance consumption under control.

Run Independent Logic in Parallel

If two or more of your tasks do not depend on each other, do not run them back to back in the same uder event script or client script flow. Instead, process them simultaneously with promise.all(), or run them in separate asynchronous tasks, the join the results with a short promise chain.

This approach may trim total run time an cause the page to be more responsive.

Batch API Calls

For any script that contains several NetSuite calls, fetch or update records in bulk before processing them in your script when possible. Placing several NetSuite API calls inside a for loop multiplies latency and may noticeably decrease performance.

Avoid Loading Records in Dynamic Mode

When possible, use the default mode to load simple records, and avoid dynamic mode when possible. Dynamic mode may be slower for loading records and may be unnecessary for certain record loads.

Only Load Modules that are Needed

Use lazy loading for modules used in your script to avoid unnecessary overhead processing.

Avoid Empty Entry Points

Do not deploy scripts with blank entry functions. They still load and may affect performance without doing any work.

Read Line Data Directly

When you need to read line data in your client scripts, use getSublistValue(), or getCurrentSublistValue(), instead of selectLine(). Using a direct read avoids UI refreshes and speeds up execution.

Write One Time, Not Repeatedly

Read necessary values one time, compute your result in memory on your script, and call setCurrentSublistValue(). Multiple writes in your script add avoidable overhead processing.

Use the Header + Child Record Pattern

If you create many records of the same type, follow the header + child pattern rather than using separate record.create() calls for each time. Instead, create one header record and add child lines in a single save operation to conserve resources and improve performance.

Optimizing UI and Client-side Performance

Load Data Only for the Most Common Path

When your user's journey contains multiple branching paths, start by loading only the records needed for the most common path. Bring in any extra data only after the user chooses a different branch.

  • Identify the main path and corner cases of your user's journey, map the branches of each sub-journey, and then determine the data required for the start of the user's journey.

    Defer the loading of other data until your user's journey requires you to load it to shorten initial load times and to focus resources on the most common use cases.

Source and Default Fields with SuiteBuilder

Avoid using user event scripts and client scripts for simple sourcing or defaulting logic. Instead, you can rely on SuiteBuilder's Field Sourcing and Default Value options to populate custom fields.

SuiteBuilder runs internally with zero script overhead and may improve your scripts' performance.

Delegate Field Visibility

When you build a localization SuiteApp, do not hard-code country-specific field visibility in your own user event scripts or client scripts. Instead, delegate that job to the Localization Assistant SuiteApp's Localization Record Context Field Management (LRCFM) component. The LRCFM component sets field visibility before a page loads, avoiding the extra client script overhead that may run unnecessarily to show or hide fields based on the country or region.

The Localization Assistant runs at load time, so you do not need to implement separate client script workarounds to set any initial visibility or to track country context changes after a user edits a form.

After installing the Localization Assistant for your SuiteApp:

  • Configure the Localization Record Context Field Management component for each record type that contains localized fields.

  • Remove any custom scripts that only show or field fields based on country context.

Optimize NetSuite Preferences

NetSuite includes many preferences that users can set to configure the system for optimum performance. Users can review available preference options at Home > Set Preferences.

Users can adjust the following preferences to speed up page loading:

  • On the Appearance subtab, in the Centers & Dashboards section, set the Landing Page preference to open NetSuite to a page other than the Home page. This preference can be set to open NetSuite on the page that a user visits most frequently.

  • On the General subtab, in the Optimizing NetSuite section:

    • Check the Delay Loading of Sublists box to initially load NetSuite pages without data on subtabs.

      When this box is checked, the data on each subtab is loaded only when the subtab is clicked, which shortens the initial page loading time.

    • Set the Number of Rows in List Segments field to a lower number to speed the loading of pages containing long lists.

      A segment size of 50 is a balanced option. When a page includes a long list of records, the list is divided into segments, with one segment loaded at a time. Lowering this preference decreases the size of each segment.

    • Set the Maximum Entries in Dropdowns field to a lower number to speed the loading of pages containing dropdown lists with lots of options.

      You should use a setting of 50 or less, unless you need larger menus. Any list with more results appears in a popup instead of a dropdown list. Using popups speeds page load time.

      • With dropdown lists, all values in a list load when a user accesses a page.

      • With popup list fields, the lists don't load until a user searches for an item or clicks the list icon. Users can quickly search and automatically complete fields by entering the first few letters of the item and pressing the Tab key.

Optimize Data Access and Queries

Query Data with SuiteQL or N/query

If your task, script, or project requires raw data for processing, write a SuiteQL statement or use the N/query module. Avoid using saved searches and N/record loads for raw data, as they create full record objects and may add the unnecessary overhead result of pagination, governance checks, and JSON serialization.

  • Skip the record-load cost with SuiteQL and N/query, as they return lightweight result sets without instantiating record objects.

  • Use query.expression filters to further optimize your N/query statements

  • Use bound parameters to further optimize your SuiteQL statements

  • Use customScriptID for efficient query calls in openSearch

Combine Data into a Single Query

Search and query performance in your script may be improved by retrieving needed data in one big query and processing the results in memory. Running the same or many queries inside a loop may add avoidable overhead and may slow every page that calls your script.

  • Write one SuiteQL or N/query statement that returns all columns and data required for your operation

    For example, if you need to process a set of invoices, you could query the entire set of invoice data, package it with N/record, and then iterate through the result set rather than calling N/record for each invoice.

Run One Query from your Client Script

When you run a client script, a browser can only send 4-8 HTTP requests concurrently. Too many N/query calls at the same time will create a queue, extend page-load times, and reduce performance for users. Browsers, not NetSuite, impose the concurrency limit on JavaScript, so even optimized queries stall when you trigger too many from your script.

  • Combine requests whenever practical and write a single SuiteQL or N/query statement that returns every column you need

  • Consider moving data collection to the backend. If you need multiple queries, use a map/reduce script, scheduled script, or RESTlet, then pass the packaged results to the client script.

    Warning:

    Do not replace many small queries with a single statement full of OR clauses or UNION statements if you have multiple queries that cannot be consolidated. This type of combined query may be worse for performance than a few target queries.

Use N/search.lookupFields()

If you need to read or look up a few field values, and you do not need to save the record, use lookupFields(). This lightweight search avoids calling record.load() and record.save for read-only data.

Optimize Search and Performance Reporting

NetSuite provides powerful search capabilities that enable retrieval of the precise information needed, from a potentially vast amount of stored data. However, searching a large number of stored records can slow the retrieval of search results.

Important:

Keep in mind:

  • Use scheduled searches where possible, even for integrations where performance is currently acceptable. Scheduled searches run in the background and can help ensure results are delivered reliably even as data sizes grow over time.

  • Perform searches and reports on a limited time range (smaller is always better).

  • Avoid including system notes in your searches because they contain a lot of data. If you have any logic based on the record history, it's preferable to have a custom field on the record itself.

For information about different types of NetSuite searches, see Search Overview. For details about preferences you can set for searches, go to Home > Set Preferences, and click field names on the Analytics subtab.

Avoiding the “Contains” Condition in Searches

The contains condition is one of the most resource-intensive search mechanisms. Try to replace this condition wherever possible to improve search performance:

  • If all of the records you want to retrieve begin with the value you're attempting to match, use “starts with” or “keywords” instead of “contains”.

    For example, if you are searching for all records for customers with names beginning with “PennyPack”, such as “PennyPack Systems-NY” and “PennyPack Systems-SF”, you can define search criteria of “Name/ID starts with PennyPack”, rather than “Name/ID contains PennyPack”.

  • If all of the records you want to retrieve contain words beginning with the value you're attempting to match, use “has keywords” instead of “contains”.

    For example, if you are searching for all records for customers with the word “Toys” in their names, you can define search criteria of “Name/ID has keywords TOYS”.

Scheduling Exceptionally Long Saved Searches

NetSuite offers the option to schedule saved searches and have results sent as an email to the recipients you choose, so you do not have to stop your work to wait for exceptionally long searches. On the Email subtab of a Saved Search definition page, you can choose the date or dates when you want to run the search, and you can select one or more recipients for emailed search results. Scheduled saved searches are run at 2 a.m. Pacific time on the dates specified. For more information, see Enabling Saved Search Scheduled Email.

Scheduling Exceptionally Long Reports

If you discover that a report takes a long time to return results, you can click Schedule in the footer of the report. Clicking the Schedule button opens the Schedule Report page where you can create a schedule to automatically send the report as an email. Schedules can be created for standard and saved reports and can be sent to other users.

On the Schedule Report page, you can select recipients, enter a message, and select attachments to include with the emailed report. You can then use the options on the Recurrence tab to define how often you want this report sent as an email to the recipients.

For more information, see Scheduling a Report.

If performance of a scheduled report or saved search is abnormally slow, use Application Performance Management (APM) to analyze the search performance of users. For details, see Analyzing Search Performance. If you require further assistance, submit a case to NetSuite Customer Support. For details, see Gathering Performance Details.

Warning:

If your report isn’t returning results quickly enough, do not repeatedly attempt to run it during the time that the original report is still running. Executing multiple reports at the same time can cause significant performance issues.

Optimize Firewalls and Proxy Servers

The following tips can be useful when setting up firewalls and proxy servers for optimal use.

Firewalls and NetSuite

A firewall is generally set up to protect your network or computer from unwanted internet traffic. The primary function of a firewall is to let good traffic pass through and block bad traffic. If your company uses a firewall to monitor internet traffic, your network manager may need to modify the firewall to use NetSuite successfully.

If you are experiencing performance issues, pages that load slowly, or frequent time-outs, try accessing NetSuite from a location outside of the firewall. If you determine that the firewall may be a problem, try making the following changes to the firewall:

  • Set up the firewall to allow all traffic to and from www.netsuite.com and any of the applicable URLs found in Understanding NetSuite URLs.

  • Open the following ports:

    • Port 80 for non-secure HTTP pages

    • Port 443 for secure HTTPS pages

    • Port 1708 for SuiteAnalytics Connect access

Proxy Servers and NetSuite

You shouldn't access NetSuite using a proxy server, if possible.

When your company uses a proxy server for internet traffic, and you visit a web page from your computer, a request is sent to the proxy server for that page. The proxy server retrieves the page from the internet and forwards the page to your computer. The page may then be cached, or saved, on the proxy server's disk drive for future use. For subsequent requests of the same page, the proxy server may return the cached version of the page stored on its drive instead of accessing a current version of the page from the internet.

Cached pages returned by a proxy server can cause problems when using NetSuite, because you need to view accurate and up-to-date information about your company.

Optimize Dashboard Portlets Configuration

NetSuite provides great flexibility for dashboard configuration, giving you the freedom to include many portlets on each page. Note that the loading of real-time data for portlets can increase page loading times. For example, Key Performance Indicators portlets and custom saved search portlets may be slow to load.

When you are setting up a dashboard, consider the following ways to manage page loading performance:

  • If you want access to a portlet's information but don't need to see it on a dashboard, consider adding a shortcut in the shortcuts portlet. For details, see Shortcuts Portlet.

  • If you want to include slow-loading portlets on a dashboard, you can avoid loading their data at initial page load by minimizing them.

    To minimize a portlet, click the portlet's title.

    The portlet stays minimized the next time you log in or refresh the dashboard. You need to click the title of the minimized portlet to display the data.

Optimizing Configuration, Deployment, and Scope

Warning:

Deploy scripts only to the specific record types that require the log. When you deploy a script to a broad category, such as item or transaction, NetSuite automatically attaches that script to every related sub-type. Your script will then run on records that do not need this script, possibly increasing page-load times and consuming extra processing power.

Manage Script Deployment Log Levels

Do not leave debug logging enabled for scripts you push to production. Instead, ensure you set each script deployment's log level to audit, error, or emergency before you move it to production.

Leaving the level at debug, especially when log.debug() calls remain inside your script, adds unnecessary overhead and inflates the script log. Ensure you log only what you need for normal operations and replace granular entries with a single summary log.

Although log.debug() is an asynchronous call, it still generates network traffic in your client scripts, adding avoidable competition for browser-limited resources.

Limit Audience and Contexts

When you deploy scripts, it is important to define the required execution contexts, event types, and audience. Limiting your script execution to only the necessary employees, roles, and contexts may help improve your performance and reduce unnecessary processing.

  • Use the N/runtime module to restrict script execution to specific roles or contexts where appropriate.

  • Configure script deployments in the NetSuite application to ensure scripts run only for the intended audiences and event types.

Migrate from Legacy Tax to SuiteTax

SuiteTax's modern process completes tax calculations faster than the Legacy Tax module. Migrate from Legacy Tax to SuiteTax where possible and you may see shorter transaction-save times and improved overall performance.

Limit Localization Record Context

When your SuiteApps include user event scripts, ensure these scripts run only in the relevant country contexts. Deploying user event scripts for all localization contexts may lead to unnecessary processing and may negatively impact performance.

Improve your script execution by using the Localization Record Context (LRC) support in the NetSuite application to limit the execution of user event scripts to specific countries. Assign a localization context to each user event script deployment to ensure scripts only run when appropriate for the country or region.

Related Topics

General Notices