Skip to main content

Rate Limits & Quotas

Salesforce enforces a rolling 24-hour API-call pool (15,000 calls on Developer Edition; 100,000+ on Enterprise) shared across REST, Bulk, and SOAP. The connectors are designed to stay well inside it.

The rate governor​

sf-core polls GET /services/data/vXX.X/limits/ (at most every 5 minutes) and tracks:

LimitUsed by
DailyApiRequestsREST calls (describe, gap re-query, composite writes, limits itself)
DailyBulkV2QueryJobsSnapshot, polling, and resync query jobs (10,000/24h)
DailyBulkApiBatchesBulk ingest (15,000/24h shared with Bulk 1.0)

Before consuming quota, the governor checks the remaining fraction; below the 5% reserve it fails the operation with a retryable error, so the task backs off with exponential backoff + jitter instead of burning the remainder of the pool. Local consumption between refreshes is tracked so the estimate stays honest.

Retry classification​

Transient failures are retried within sf.request.max.retries.time.ms (exponential backoff with jitter):

  • HTTP 429 and all 5xx
  • HTTP 403 with REQUEST_LIMIT_EXCEEDED
  • gRPC UNAVAILABLE, DEADLINE_EXCEEDED, RESOURCE_EXHAUSTED
  • Network timeouts and connection resets
  • 401/INVALID_SESSION_ID triggers one transparent re-authentication

Everything else (validation errors, INVALID_FIELD, …) fails fast — per-record where possible (DLQ), otherwise the task.

Keeping API usage low​

  • Event-driven mode is nearly free — the Pub/Sub gRPC stream doesn't consume the REST API pool; describe results are cached with If-Modified-Since (304s are cheap).
  • sf.full.record.on.update=false (default) avoids one REST call per UPDATE event.
  • Polling mode costs one Bulk query job per object per interval — with the default 30s interval that's ~2,880 jobs/day per object against the 10,000/day allocation; size sf.poll.interval.ms accordingly.
  • Sink: prefer sf.write.mode=auto — large batches use one Bulk job instead of many Composite calls (a Composite call writes up to 200 records per API call).