Zoho CRM API Limits: How to Handle High Volumes
How Zoho CRM API credits and concurrency work, and the design patterns that keep high-volume integrations within limits.

Understand Zoho CRM API limits, credits and concurrency, then cut usage with bulk APIs, delta syncs and queues. Includes a worked rate-aware client.
Every Zoho CRM integration eventually meets the same wall. A sync that worked perfectly in testing starts returning errors in the afternoon, or a nightly import stops halfway with a message about too many requests. Zoho CRM API limits are designed to keep the platform fair and stable for everyone, and they are entirely workable once you understand them. You cannot bypass them, but you can design so that you rarely touch them. This guide explains how credits and concurrency work, which calls cost the most, and the patterns we use to keep high-volume integrations running smoothly, including a worked credit budget and a rate-aware Python client.
How Zoho CRM API limits work
Zoho applies two separate kinds of limit, both described in its API limits documentation.
Credits over a rolling 24-hour window
Each API call deducts credits from your organisation's allowance. The allowance depends on your edition, the number of user licences and any add-on credits you buy. The window is rolling, so a burst of calls at 10 a.m. counts against you until 10 a.m. the next day.
Concurrency and sub-concurrency
Concurrency limits cap how many calls can be in progress at the same moment, per organisation and per app. According to Zoho's documentation, the limits are 5 for Free, 10 for Standard, 15 for Professional, 20 for Enterprise and 25 for Ultimate. Some heavier calls also share a sub-concurrency limit of 10 across all editions. Zoho's Kaizen post on credit calculation and concurrency lists them, including insert, update or upsert calls with more than ten records, COQL queries, composite requests and lead conversion.
When either limit is exceeded, the API returns a TOO_MANY_REQUESTS error.
Which calls cost the most
Credit costs vary widely by call type. A few examples from Zoho's documentation:
CallCreditsInsert, update or upsert records1 credit per 10 records (up to 100 records per call)Get records with a custom view ID (cvid)3COQL query1 to 3, depending on the LIMIT valueConvert lead5Send mail20Bulk read initialise50Mass change owner, merge records50
The practical lesson is that batch sizes matter enormously. Updating 100 records in one call costs 10 credits; updating them one at a time costs 100.
Design patterns that keep you inside Zoho CRM API limits
Batch every write
Always send up to 100 records per insert, update or upsert call. If your integration processes events one by one, collect them in a short buffer and flush in batches.
Read only what has changed
Polling an entire module every few minutes is the most common cause of credit exhaustion we see. Instead, request records modified since your last successful sync. The Get Records API supports an If-Modified-Since header for this.
Use the right tool for large reads
For exports of many thousands of records, use the Bulk Read API, which runs asynchronously and returns a file, rather than paging through records one call at a time. For selective reads, COQL can fetch exactly the fields and records you need.
Combine related requests
The Composite API lets you group several API requests into one call. It is useful when one operation needs a few dependent steps.
Cache what rarely changes
Field metadata, layouts, users and picklist values change rarely. Cache them for hours rather than fetching them on every run.
Control concurrency centrally
If several services call Zoho with the same app, they share the same concurrency limit. Route calls through one client or queue that enforces a cap below your edition's limit, and keep heavier calls below the sub-concurrency limit.
Back off, do not hammer
When you receive TOO_MANY_REQUESTS, wait and retry with increasing delays. Immediate retries use up concurrency slots and make the problem worse.
Worked example: a daily credit budget
Before building an integration, estimate its daily credit use. The figures below are an illustrative budget for an e-commerce store syncing orders and customers into Zoho CRM.
JobVolume per dayMethodCredits per dayUpsert new and changed contacts3,000 recordsUpsert, 100 per call (30 calls × 10)300Create deals from orders1,500 recordsInsert, 100 per call (15 calls × 10)150Fetch contacts changed in CRMEvery 15 minutesGet Records with If-Modified-Since, 1 page each (96 calls × 1)96Nightly export for reporting1 jobBulk read initialise50Metadata refreshTwice a dayGet field metadata (2 calls × 1)2Total598
Compare the total with your organisation's allowance, which you can calculate from Zoho's documentation, and leave generous headroom for other integrations and growth. If the same jobs were written to update one record per call and poll the whole contact list, the budget would be many times higher.
Worked example: a rate-aware Python client
The illustrative client below caps concurrent calls with a semaphore and backs off when Zoho reports it is busy. All your services would use this one client, so the cap applies across them.
import threading, time, requests
class ZohoClient:
def __init__(self, api_domain, token_provider, max_concurrent=8):
self.base = f"{api_domain}/crm/v8"
self.get_token = token_provider # returns a fresh access token
self.slots = threading.BoundedSemaphore(max_concurrent)
def request(self, method, path, params=None, json=None):
for attempt in range(6):
with self.slots: # never exceed the cap
headers = {"Authorization": f"Zoho-oauthtoken {self.get_token()}"}
r = requests.request(method, f"{self.base}{path}", headers=headers,
params=params, json=json, timeout=60)
if r.status_code == 429 or "TOO_MANY_REQUESTS" in r.text:
time.sleep(min(pow(2, attempt) * 3, 120))
continue
r.raise_for_status()
return r.json() if r.content else {}
raise RuntimeError(f"{method} {path} still rate-limited after retries")
def upsert(self, module, records, dedupe_fields):
results = []
for i in range(0, len(records), 100): # 100 records = 10 credits
body = {"data": records[i:i + 100], "duplicate_check_fields": dedupe_fields}
results.extend(self.request("POST", f"/{module}/upsert", json=body)["data"])
return results
Set max_concurrent comfortably below your edition's limit, and lower still if heavy calls make up most of your traffic.
Monitoring credit use
Zoho shows API usage in the CRM's developer settings, and your own logs should record credits per job. We add a daily report of credits used by each integration, with an alert when usage passes a threshold such as 70 percent of the allowance. That gives you time to fix a misbehaving job before it blocks everything else.
When to buy more credits
Add-on credits are a reasonable answer once your integrations are efficient and your volume has genuinely grown. They are a poor answer to polling, one-record-per-call updates or duplicate integrations doing the same work. Fix the design first, then size the allowance.
For very large updates, our guide to Zoho CRM mass update options and decoupled batch workers shows how to process hundreds of thousands of records safely. For scheduled processing inside Zoho itself, see architecting custom schedulers in Zoho CRM.
Frequently Asked Questions
What are the Zoho CRM API limits?
Zoho limits API use by credits over a rolling 24-hour window, based on edition, user licences and add-on credits, and by concurrency per organisation and app. Zoho's API limits documentation lists both.
What does TOO_MANY_REQUESTS mean in Zoho CRM?
It means you have used up your credit allowance for the window or exceeded the concurrency or sub-concurrency limit. Back off and retry with increasing delays, and review your batching and polling.
Can we bypass Zoho CRM API limits?
No, and you should not try. You can reduce usage dramatically by batching writes, reading only changed records, using bulk APIs for large jobs and controlling concurrency. Add-on credits are available when genuine volume requires them.
Do Deluge functions count against API limits?
Deluge integration tasks call the APIs behind the scenes and count against limits, and functions also have their own execution limits. Batch operations inside functions in the same way.
Make your integrations limit-proof with us
We design Zoho CRM integrations that stay within credits and concurrency at high volume, with monitoring that warns you early. See our CRM and API integration services, or talk to us about your Zoho integration.
About the Author
Manav Sharma is the founder of Insyrge and a CRM solutions architect. He works across Zoho, Salesforce, HubSpot, Odoo and more, designing the CRM setups, integrations and automations that keep sales and operations teams working from the same data.
Need Help Implementing This in Your Business?
Our certified Zoho consultants and automation experts can help you design and deploy custom workflows tailored to your operations.
Book Free Consultation