πΉ Why Performance Optimization Matters
NetSuite scripts run on usage governance limits and system resources. Poorly optimized scripts can:
β Timeout or exceed governance limits
β Lock records and slow down transactions
β Cause errors during peak loads
β Deliver poor user experience
Optimizing scripts ensures:
β
Faster execution
β
Lower governance usage
β
Scalability for large datasets
β
Better reliability
πΉ Key Areas to Optimize
- Governance Management
- Each API call consumes governance units.
- Example:
record.load()costs more than usingsearch.lookupFields().
- Efficient Searches
- Use Saved Searches or SuiteQL instead of looping
search.run().each(). - Fetch only required fields.
- Use paged searches for large result sets.
- Use Saved Searches or SuiteQL instead of looping
- Bulk Processing
- Use Map/Reduce scripts instead of Scheduled scripts for large data.
- Use getInputData efficiently to stream search results.
- Minimal Record Loads
- Avoid loading entire records when only one field is needed.
- Use
lookupFieldsorsearch.lookupFields.
- Caching
- Store reusable data (e.g., exchange rates, account IDs) with
N/cache. - Reduces repeated lookups.
- Store reusable data (e.g., exchange rates, account IDs) with
- Asynchronous Work
- Offload heavy processing with Map/Reduce or Scheduled Scripts.
- Trigger async work from User Event scripts.
- UI Responsiveness (Suitelets & Client Scripts)
- Keep Suitelets lightweight: show progress and push bulk processing to Map/Reduce.
- Use client validation instead of server calls where possible.
πΉ Code Examples
1) Expensive (Bad) vs Optimized (Good)
β Bad: Loading full record for one field
// Costly approach
var rec = record.load({ type: 'customer', id: 123 });
var email = rec.getValue('email');
β Good: Lookup only needed field
// Efficient approach
var email = search.lookupFields({
type: 'customer',
id: 123,
columns: ['email']
}).email;
2) Using SuiteQL for Bulk Fetch
/**
* Example: Fetch customers with SuiteQL
*/
const sql = `
SELECT id, entityid, email
FROM customer
WHERE isinactive = 'F'
LIMIT 100
`;
const results = query.runSuiteQL({ query: sql }).asMappedResults();
results.forEach(r => {
log.debug('Customer', r.entityid + ' | ' + r.email);
});
β Faster than running searches with multiple joins.
3) Using Caching (N/cache)
/**
* Example: Cache exchange rate lookups
*/
define(['N/cache'], cache => {
const exchangeCache = cache.getCache({ name: 'exchange_rates' });
function getRate(currencyId) {
return exchangeCache.get({
key: currencyId,
loader: () => {
// Simulate API call or record lookup
log.debug('Cache Miss', 'Fetching from source');
return '1.25';
}
});
}
return { getRate };
});
β Prevents repeated expensive lookups.
4) Governance Handling in Map/Reduce
/**
* Example: Yield execution if governance is low
*/
function map(context) {
try {
if (runtime.getCurrentScript().getRemainingUsage() < 200) {
// Let NetSuite auto-resume
return;
}
// Process logic here
} catch (e) {
log.error('Error in Map', e);
}
}
πΉ Best Practices Checklist
- β Use Map/Reduce for big data (invoices, orders, journal entries).
- β Avoid synchronous loops over thousands of records.
- β
Use lookupFields & SuiteQL instead of
record.load(). - β Batch writes instead of saving one record at a time.
- β Log smartly (only key info, avoid logging inside huge loops).
- β Use cache for reference data.
- β Design for resumability (scripts should pick up where they left off).
β Summary
Performance optimization in NetSuite scripting is about working smarter, not harder.
By managing governance units, leveraging SuiteQL, caching, and Map/Reduce, you ensure your solutions are scalable, fast, and reliable.
Leave a Reply