Skip to content

Rate Limits & Quotas

Spooled Cloud enforces rate limits and quotas to ensure fair usage and platform stability. Limits vary by plan tier and can be increased for Enterprise customers.

Plan Comparison

Resource FreeStarterProEnterprise
Jobs per day 1,00010,000100,000Unlimited
Active jobs 105005,000Unlimited
Queues 21050Unlimited
Workers 1525Unlimited
API keys 2525Unlimited
Schedules 11050Unlimited
Workflows 525Unlimited
Webhooks 1520Unlimited
Max payload size 64 KB256 KB1 MB5 MB
API rate (req/sec) 525100500
API burst 10502001000
Job retention 3 days14 days30 days90 days
History retention 1 days7 days30 days90 days

Rate Limiting

API rate limits use a sliding window algorithm. When you exceed the limit, requests return 429 Too Many Requests with a Retry-After header.

Rate Limit Headers

Every API response includes rate limit information:

HTTP/1.1 200 OK
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 95
X-RateLimit-Reset: 1705320000
Header Description
X-RateLimit-Limit Maximum requests per window
X-RateLimit-Remaining Requests remaining in current window
X-RateLimit-Reset Unix timestamp when the window resets

Handling Rate Limits

Note: This example uses SDK syntax (under development). For production today, use the equivalent REST API with standard HTTP error handling.

import { SpooledClient, RateLimitError } from '@spooled-cloud/sdk';

const client = new SpooledClient({ apiKey: process.env.SPOOLED_API_KEY! });

async function createJobWithRetry(payload, maxRetries = 3) {
  for (let attempt = 0; attempt < maxRetries; attempt++) {
    try {
      return await client.jobs.create(payload);
    } catch (error) {
      if (error instanceof RateLimitError) {
        const retryAfter = error.retryAfter || 1;
        console.log(`Rate limited, retrying in ${retryAfter}s...`);
        await sleep(retryAfter * 1000);
        continue;
      }
      throw error;
    }
  }
  throw new Error('Max retries exceeded');
}

Quota Enforcement

Quotas are enforced at different granularities:

Daily Quotas

Jobs per day resets at midnight UTC. When exceeded:

{
  "error": {
    "code": "quota_exceeded",
    "message": "Daily job quota exceeded",
    "quota": {
      "limit": 1000,
      "used": 1000,
      "resets_at": "2025-01-16T00:00:00Z"
    }
  }
}

Resource Quotas

Resource limits (queues, workers, etc.) return:

{
  "error": {
    "code": "resource_limit_exceeded",
    "message": "Maximum queues limit reached",
    "limit": 2,
    "current": 2,
    "resource": "queues"
  }
}

Payload Size

Job payloads exceeding the limit are rejected:

{
  "error": {
    "code": "payload_too_large",
    "message": "Payload exceeds maximum size",
    "max_bytes": 65536,
    "actual_bytes": 128000
  }
}

Monitoring Usage

Track your usage via the API or dashboard:

# Get current usage
curl https://api.spooled.cloud/api/v1/usage \
  -H "Authorization: Bearer YOUR_API_KEY"

# Response shows usage for the current period

The response includes job counts, resource usage, and API call statistics for the current period.

Increasing Limits

Upgrade Your Plan

The easiest way to get higher limits is to upgrade to a paid plan at /pricing.

Enterprise Custom Limits

Enterprise customers can negotiate custom limits. Contact sales@spooled.cloud to discuss your requirements.

Self-Hosted

Self-hosted deployments can configure custom limits via environment variables or the plans.toml configuration file.

Best Practices

  • Batch operations — Use bulk endpoints (/jobs/batch) to reduce API calls
  • Implement backoff — Use exponential backoff when rate limited
  • Monitor usage — Set up alerts before hitting quotas
  • Use idempotency keys — Safely retry without creating duplicates
  • Consolidate payloads — Keep payloads small to stay within limits

Need Higher Limits?