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
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.
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.
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.
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
/**
* @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