SSS_TIME_LIMIT_EXCEEDED — what it means and how to fix it
SSS_TIME_LIMIT_EXCEEDED: It means a SuiteScript ran longer than the time NetSuite allows for that script type - for example a scheduled or user-event script exceeding its execution window. It signals that the work belongs in an asynchronous script such as Map/Reduce, or that a loop does too much per execution.
When you see this
- A scheduled or Map/Reduce script processing a large dataset stops partway with SSS_TIME_LIMIT_EXCEEDED.
- A user-event script doing heavy work (many searches or record loads) on save times out and blocks the transaction.
- A script that ran fine on small data fails once volume grows at month-end or after go-live.
Causes
- The script type's execution-time limit was hit. Each script type has a maximum run time; long loops, large searches or many record loads exhaust it.
- Synchronous heavy work in the wrong script type - doing bulk processing in a user-event or scheduled script instead of an asynchronous Map/Reduce that splits work into stages.
- Inefficient queries - loading full records in a loop, or running a search inside a loop, instead of a single search returning the columns needed.
Fix
Move bulk work to an asynchronous script that NetSuite can stage and resume, and cut the work done per execution.
- Re-platform bulk processing as a Map/Reduce script. Map/Reduce splits the job into getInputData, map and reduce stages that NetSuite schedules independently, so no single execution hits the time limit.
- Replace record.load-in-a-loop with a single search that returns only the fields you need; load the full record only when you must write to it.
// one search instead of N loads var s = search.create({ type:'invoice', filters:[...], columns:['entity','total'] }); - In a scheduled script, checkpoint and yield before the limit using runtime.getCurrentScript().getRemainingUsage() and nlapiYieldScript/rescheduling, so long jobs resume instead of timing out.
- Keep user-event scripts light - defer heavy processing to an asynchronous script triggered after the save, so the transaction is not blocked by a long-running beforeSubmit/afterSubmit.
Prevent it
- Use Map/Reduce for anything that processes more than a handful of records - design for volume, not just the test dataset.
- Prefer a single search over loading records in a loop; request only the columns you need.
- Monitor remaining usage and time, and yield or stage work before the limit.
- Keep user-event scripts minimal; push bulk or slow work to asynchronous scripts.
SuiteScript version note: SSS_TIME_LIMIT_EXCEEDED applies in SuiteScript 2.0 and 2.1; Map/Reduce (the recommended fix) is a 2.x script type. SuiteScript 1.0 used scheduled scripts with nlapiYieldScript for the same staging pattern.
Frequently asked questions
- Is this the same as SSS_USAGE_LIMIT_EXCEEDED?
- No. SSS_USAGE_LIMIT_EXCEEDED is about governance units (API calls), while SSS_TIME_LIMIT_EXCEEDED is about elapsed execution time. They often appear together on heavy scripts, and the fix overlaps: do less per execution and move bulk work to Map/Reduce.
- My script works on small data but fails at month-end - why?
- Time limits are hit by volume. Code that loops over a few records runs fine but exceeds the execution window over thousands. Design for the largest realistic dataset, not the test sample, and use an asynchronous script.
- How do I process a large dataset without timing out?
- Use a Map/Reduce script. It splits work into stages NetSuite schedules separately, so each execution stays within the limit while the whole job completes across many executions.
Last reviewed: by Wouter Nortje, CA