IntegriWorks

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.

  1. 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.
  2. 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'] });
  3. 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.
  4. 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