Limits and quotas
Rate limits, payload limits, and per-tier quotas
npayload enforces limits to ensure platform stability and fair usage. Limits vary by billing tier.
API rate limits
Requests per second, per API key:
| Operation | Free | Pro | Enterprise |
|---|---|---|---|
| Publish | 100 | 1,000 | Unlimited |
| Subscribe | 50 | 500 | Unlimited |
| Query | 200 | 2,000 | Unlimited |
Rate limits are applied per API key, not per organisation. If you have multiple API keys, each has its own limit.
Payload limits
| Limit | Value |
|---|---|
| Max message size | 256 KB |
| Max batch size | 100 messages |
| Max batch payload | 10 MB |
| Max channel name length | 256 characters |
Resource limits
| Resource | Free | Pro | Enterprise |
|---|---|---|---|
| Channels per app | 1,000 | 10,000 | Unlimited |
| Subscriptions per channel | 100 | 1,000 | Unlimited |
| Consumer group size | 10 | 100 | Unlimited |
| Apps per organisation | 3 | 20 | Unlimited |
| API keys per app | 5 | 50 | Unlimited |
| Webhook endpoints per subscription | 1 | 1 | 1 |
| DLQ entries per channel | 10,000 | 100,000 | Unlimited |
| Event catalogue schemas per app | 50 | 500 | Unlimited |
Rate limit response headers
Every API response includes rate limit headers:
| Header | Description |
|---|---|
X-RateLimit-Limit | Maximum requests allowed per window |
X-RateLimit-Remaining | Requests remaining in the current window |
X-RateLimit-Reset | Unix timestamp when the window resets |
Retry-After | Seconds to wait before retrying (only on 429 responses) |
Handling 429 responses
When you exceed a rate limit, the API returns 429 Too Many Requests. Use exponential backoff with the Retry-After header:
import { NPayload, RateLimitError } from '@npayload/node';
const npayload = new NPayload({
clientId: process.env.NPAYLOAD_CLIENT_ID,
clientSecret: process.env.NPAYLOAD_CLIENT_SECRET,
});
async function publishWithBackoff(channel: string, payload: unknown) {
const maxRetries = 5;
for (let attempt = 0; attempt < maxRetries; attempt++) {
try {
return await npayload.messages.publish({ channel, payload });
} catch (error) {
if (error instanceof RateLimitError && attempt < maxRetries - 1) {
const delay = error.retryAfter
? error.retryAfter * 1000
: Math.pow(2, attempt) * 1000;
await new Promise((resolve) => setTimeout(resolve, delay));
continue;
}
throw error;
}
}
}Do not retry immediately after a 429 response. Always wait for at least the duration specified in the Retry-After header. Repeated rapid retries may result in extended throttling.
Requesting limit increases
If your use case requires higher limits:
- Pro tier: Upgrade from Free to Pro for 10x higher limits across all resources
- Enterprise tier: Contact sales for custom limits tailored to your workload
- Temporary increases: For planned traffic spikes (product launches, migrations), contact support at least 48 hours in advance
Enterprise customers can request custom limits for any resource. Contact sales@npayload.com to discuss your requirements.
Next steps
- Rate limits for per-endpoint rate limits and best practices
- Error codes for handling rate limit and quota error responses
- Security for authentication and access control
Was this page helpful?