Skip to content
Desktop Accounting API

Rate limits and throughput

Two limits protect the service, and one limit comes from QuickBooks itself. In practice the QuickBooks limit is the one you notice.

Each project can make 1,000 requests per 10 seconds, across all its keys and end users. Above that, the API returns 429 RATE_LIMITED with details.scope: "project" and a Retry-After header in seconds. Nothing was queued, so the request is safe to retry after the wait.

Every authenticated response carries RateLimit-Limit, RateLimit-Remaining, RateLimit-Reset (seconds) and RateLimit-Policy: 1000;w=10. The limit is enforced across our edge network, so Remaining and Reset are estimates from the server that answered. Treat a 429 with Retry-After as authoritative.

Two limits protect against abuse before a key is even checked: 2,000 requests per 10 seconds from one IP address, and 20 failed authentications per minute from one IP address, after which that address is refused for 60 seconds. Both return 429 RATE_LIMITED with details.scope: "ip". A correctly configured server never meets them.

Each connection (one company file) accepts:

  • at most 200 pending requests (queued, waiting or sent), and
  • at most 50 sync callers waiting at the same time.

Beyond either limit, the API returns 429 CONNECTION_QUEUE_FULL with details.reason (pending_requests or sync_waiters). Nothing was queued. This usually means a loop is sending requests faster than QuickBooks can answer them. Async requests do not count toward the sync waiter limit, so batches belong in async mode.

QuickBooks Desktop processes one request at a time for each company file, on your customer’s computer. A simple read in a warm session takes well under a second; a large report can take minutes. So:

  • Parallelize across end users, not within one. Requests for different company files run independently. Sending ten parallel requests for one file only lengthens its queue.
  • Ask for more per request. Use limit up to 150 on cursor lists, and filters such as updatedAfter, instead of retrieving records one by one.
  • Use async mode for batches. Queue the writes with Prefer: respond-async and let webhooks tell you as each one completes. The queue keeps order, and your workers do not sit on open HTTP calls.
  • Keep the session warm. A request sent within about 2 seconds of the previous one finishing reuses the open QuickBooks session and skips the Web Connector check-in.

The SDKs retry 429 responses automatically, waiting for Retry-After, up to their retry limit (two retries by default). For raw HTTP:

  1. Read Retry-After and wait that many seconds.
  2. Retry the same request. For writes, reuse the same Idempotency-Key.
  3. If you keep hitting CONNECTION_QUEUE_FULL for one end user, reduce that end user’s concurrency rather than retrying harder.
Limit Value Error
Request body 20 MiB 413 PAYLOAD_TOO_LARGE
Values in one array query parameter 100, unless the operation says otherwise 400 INVALID_PARAMETER
Page size on cursor lists 1 to 150 400 INVALID_PARAMETER
Sync wait (Daapi-Timeout-Seconds) 1 to 300 seconds 400 INVALID_PARAMETER
Async queue lifetime (Daapi-Queue-Ttl-Seconds) 10 to 86400 seconds 400 INVALID_PARAMETER
QuickBooks response Very large unpaged responses 422 QBD_RESPONSE_TOO_LARGE