Skip to content
Error ResolutionRESTletsSuitelets

Fix: SSS_REQUEST_LIMIT_EXCEEDED — NetSuite Concurrency Limit Error

Too many simultaneous requests hit the same script deployment. Here's what the limits actually are and how to stay under them.

SSS_REQUEST_LIMIT_EXCEEDED: You have exceeded the maximum number of requests allowed for this script.

Quick Reference

Error Code
SSS_REQUEST_LIMIT_EXCEEDED
Severity
high
Type
script
Versions
2024.1, 2024.2, 2025.1, 2025.2, 2026.1

Why This Happens

  • Multiple external systems hitting the same RESTlet deployment simultaneously
  • A single integration sending requests faster than NetSuite can process them — no rate limiting on the client side
  • Multiple Scheduled Script deployments of the same script running at the same time
  • Webhook-style integrations that burst during high-activity periods (e.g., e-commerce order rushes)
  • Load testing or migration scripts hammering a RESTlet without concurrency controls

How to Fix It

  1. Step 1: Understand the concurrency limits

    NetSuite allows a maximum of 30 concurrent requests per deployment for RESTlets/Suitelets (exact limit depends on your SuiteCloud Plus license tier). Scheduled Scripts are limited to 1 concurrent execution per deployment. If you need more throughput, create additional deployments of the same script.

  2. Step 2: Implement client-side rate limiting

    Your integration should throttle requests to NetSuite. A simple approach: send no more than 10 concurrent requests and use exponential backoff when you receive 429 or SSS_REQUEST_LIMIT_EXCEEDED errors. Most HTTP libraries support retry-with-backoff natively.

  3. Step 3: Create multiple deployments

    Each script deployment has its own concurrency pool. If you need 60 concurrent requests, create 2 deployments and round-robin between them. Use a load balancer or simple rotation logic in your integration.

  4. Step 4: Batch requests instead of sending one per record

    Instead of sending 1,000 individual record update requests, design your RESTlet to accept an array of updates in a single request. Process them in a loop server-side. This reduces concurrency from 1,000 to 1 request (which might then need Map/Reduce for governance).

Code Example

batch-restlet.jsGov: 10u
/**
 * @NApiVersion 2.1
 * @NScriptType Restlet
 *
 * Pattern: batch RESTlet that processes multiple records per request.
 * Reduces concurrency pressure vs sending one request per record.
 */
define(['N/record', 'N/log'], (record, log) => {

  /**
   * POST handler — accepts an array of update objects.
   * @param {Object} body - { updates: [{ type, id, values }] }
   * @returns {Object} - { results: [{ id, success, error? }] }
   */
  function post(body) {
    const updates = body.updates || [];

    if (updates.length === 0) {
      return { results: [], message: 'No updates provided' };
    }

    if (updates.length > 50) {
      return { error: 'Batch size exceeded. Maximum 50 records per request.' };
    }

    const results = updates.map((update) => {
      try {
        record.submitFields({
          type: update.type,
          id: update.id,
          values: update.values
        });
        return { id: update.id, success: true };
      } catch (e) {
        log.error('Batch update failed', `${update.type} #${update.id}: ${e.message}`);
        return { id: update.id, success: false, error: e.message };
      }
    });

    const succeeded = results.filter((r) => r.success).length;
    log.audit('Batch complete', `${succeeded}/${results.length} succeeded`);

    return { results };
  }

  return { post };
});

Common Mistakes

  • Creating only one deployment and expecting it to handle unlimited concurrent requests
  • Not implementing retry logic on the client side — SSS_REQUEST_LIMIT_EXCEEDED is transient, not permanent
  • Using synchronous HTTP calls from another SuiteScript to call a RESTlet — this consumes governance on both sides
  • Running a data migration by firing thousands of parallel requests at a RESTlet — use CSV Import or Map/Reduce instead

Alternative Approaches

  • For bulk data import, use CSV Import (task.create with TaskType.CSV_IMPORT) instead of RESTlet calls — no concurrency limits
  • For event-driven integrations, consider SuiteScript User Events or Workflows instead of external webhook → RESTlet patterns
  • Use the SuiteTalk REST Web Services API (record API) for CRUD operations — it has higher concurrency limits than RESTlets in most configurations

Related Errors