Rate limiting in Bitrix24: why integrations fail
The portal counts REST calls across several counters at once: the overall request rate from the application, the load on individual methods, and the concurrency of requests.
As soon as an integration with external systems consumes its share, the response returns a request limit exceeded error — most often QUERY_LIMIT_EXCEEDED, sometimes an empty response with no body or data.
From the outside, this looks like a broken exchange: deals and tasks stop updating, even though both systems are alive and available.
The cost of such an exchange error is not in a single failed call.
Background jobs do not distinguish between "limit exhausted" and "data has not changed," so they repeat the request in full; when resending without an idempotency key, some operations are duplicated and some are lost in the middle of a batch.
Tracing the aftermath retrospectively is almost impossible — the log shows only the fact of the refusal, without indicating what exactly managed to apply.
Then the cumulative effect kicks in. The external system generates events faster than the portal accepts them, the background job queue grows faster than it is processed, and retries without a pause add load and themselves bring the next failure closer.
Mass imports accelerate this many times over: they consume the limit differently from single calls and crowd out the exchange that previously worked normally.
We will look at how this is addressed in practice: under rate limiting in Bitrix24, a custom call scheduler is built, the load is spread over time, and retries are made safe — so that the exchange completes fully and the job queue does not grow faster than it is processed.
What changes after configuring request limits
Managed request rate (rate limiting) changes integration behavior immediately.
Instead of a burst of parallel calls that hits QUERY_LIMIT_EXCEEDED and loses some operations, an exchange queue appears: requests are sent in batches, with pauses and retries for those that returned with an error.
Limits in Bitrix24 are counted separately for the application and for the user, so the queue is built around both counters, not the total number of calls.
Load smoothing is visible in the metrics. Exchange time stops depending on the volume of a one-time export: where synchronization of reference data and deals was interrupted halfway and restarted from scratch, the work completes in a single pass.
The share of exchange failures drops from percentages to isolated cases, and nightly synchronization fits within the allotted window.
Peak windows are a separate case. The morning surge in activity, mass import of catalog items, distribution across leads: previously each such surge competed with the integration for the same limit, now the background queue yields to interactive requests and waits for its lane.
For integration stability, not only a pause but also the predictability of retries matters: immutability of operations on resend, preservation of queue state between restarts, and a failure log.
Documentation on request limits sets thresholds, but it does not replace measurements on the real load profile — we take them before and after configuration and show the difference for each metric.
Bitrix24 limits: API access options
Bitrix24 REST returns the QUERY_LIMIT_EXCEEDED error not when "the server is overloaded," but when the application has exceeded the agreed call rate.
The symptom is the same — a refusal in the response — while the causes differ: a loop over a list without pauses, straightforward reference data synchronization, polling for changes every minute.
The access method must be chosen before writing code: reworking exchange logic after the fact is more expensive than building in a job scheduler or event model from the start.
| Option | When it fits | Limitations |
|---|---|---|
| Client-side queue with retries | 2-3 exchange scenarios, the call stream is small and predictable | during a burst, retries consume the same quota; you need increasing pauses between attempts and a shared counter |
| Scheduled batch processing | reference data synchronization, reports, exchange once an hour or less often | data lags; launch windows must be spread out, otherwise jobs overlap |
| Middleware between systems | multiple sources and consumers, a unified log and resend are needed | a separate service: it must be maintained, monitored, and updated |
| Event model instead of polling | reaction to entity changes is needed immediately | depends on event completeness; some data still has to be fetched with targeted calls |
| Manual procedures | one-time exports, infrequent reconciliations | human factor, no idempotency, retry produces duplicates |
What is done in practice
Most often it is a combination: an event model handles real-time reactions, a scheduler catches up on what was missed, and request rate limiting is moved into a separate layer that accounts for the quota. Below we look at how such a layer is structured.
How we build request rate limiting
Before changing integration code, we measure the real load: how many requests per minute go to Bitrix24, which scenarios produce peaks, and at what point the portal responds with QUERY_LIMIT_EXCEEDED.
Without these measurements, any rate limiting configuration becomes blind guesswork — the limits either cut off useful requests or do not protect against cascading failures. Then the work proceeds in steps.
- Audit of integrations. We collect all exchange points — event handlers, exchange with 1C, external services, background tasks — and record the peak rate and failure share for each.
- Exchange scheme. We distribute requests by priority: critical operations (deals, invoices, order statuses) go in a separate stream, mass synchronizations in another. We separate them so that batch export does not block urgent calls.
- Queue configuration. We introduce a buffer in front of the portal with a limit per application and per method, level out peaks, and smooth bursts from webhooks.
- Retry rules. We configure retries with increasing delay, account for the
Retry-Afterheader, and make operations idempotent — a retry does not create duplicates. - Test environment. We run scenarios with an artificial peak several times higher than production, observe how the queue behaves, and whether the exchange recovers after a series of failures.
- Rollout. We enable limits gradually, tracking the failure share, queue depth, and processing delay.
- Handover to support. We give the support team the limit procedures, dashboard, and alert thresholds so that the rules do not diverge as load grows.
On output, exchange stops hitting the portal limits, and behavior under load becomes predictable.
Configurations, procedures, and documentation delivered
Configuring limits is not a single code change but a set of artifacts that remain in the customer's repository. They are enough for a new engineer to understand the exchange with Bitrix24 in a couple of days and be able to change call intensity without rereading all the code. Below is what exactly we hand over.
- Exchange scheme: which methods are called, at what frequency, who initiates — the portal or the external system, where the retry points are, and how the daily load profile is distributed.
- Queue and schedule settings: batch size, polling interval, scenario priorities, windows for heavy exports moved outside peak hours.
- Retry rules: increasing delay between attempts, attempt count ceiling, separation of errors into temporary and permanent, procedure for processing the unprocessed remainder.
- Failure handling: behavior on a response with limit exceedance, the moment the counter resets, degradation scheme — the call goes into the queue instead of a direct request.
- Observation logs: share of responses with limit refusal, queue depth, batch traversal time, ready-made panels and thresholds that trigger alerts.
- Support procedures: who reviews the logs and how often, what to do during a burst, in what order limit changes are approved.
- Integration documentation: map of methods used, current limits, configuration examples, and a checklist for connecting a new exchange scenario.
Each item is backed by a working config, not a description of "how it should be done." This is what makes it possible to support the integration with your own team — without coming back to us for every intensity change.
Case: 1C exchange stopped failing due to limits
On the reference project, exchange between 1C and the portal ran in batches of several hundred catalog items.
During peak windows — month-end closing, mass price updates — the request counter hit the method limit, some calls returned QUERY_LIMIT_EXCEEDED, and the exchange stopped in the middle of a batch.
Picture before the changes: the share of failed operations held around 18%, a full exchange took 4–5 hours and spilled beyond the nightly window, and the morning run picked up underloaded batches again. Clearing the backlog cost the team 6–8 manual fixes per week.
What we did
We moved calls into a queue with request rate limiting (rate limiting) below the method threshold, added a pause with increasing interval between retries and idempotency keys for write operations — a retry stopped creating a duplicate.
We split batches by execution time, not by number of records: a burst on one reference book no longer blocks the others.
What changed
The share of failed operations fell from 18% to fractions of a percent, a full exchange fits into 1.5–2 hours, manual fixes per week — 6–8 → 0–1. Recovery time after a failure dropped from several hours of manual analysis to restarting the queue.
The class of failures under peak load has been eliminated: the limit no longer stops the exchange — the queue simply stretches over time, and unfinished operations arrive in the next pass.
Monitoring sees queue fill and retry count, so we learn about degradation earlier than accounting asks about it.
What to do if the exchange already works without limits
An existing integration is almost never "clean": parallel handlers, repeated calls in loops, manual exports in the common stream.
Therefore, managed request rate is introduced not instead of the current scheme but on top of it: the limiter is placed on outgoing calls — first in observation mode, where it only counts requests by method, distributes them by second, and shows where scenarios hit QUERY_LIMIT_EXCEEDED, without blocking anything.
Then phased implementation: first a soft threshold, when exceedance is not rejected with an error but goes into the queue with a delay; then a hard threshold; and only after that scenario priorities and cleanup of accumulated records.
Backward compatibility rests on the fact that the scenario still receives a response — just not instantly — and contracts and data formats do not change.
Without stopping the exchange, thresholds, delays, method composition, queue priorities, and timeouts can be changed: this is configuration that the handler rereads on the fly.
A pause window is mandatory where semantics change — the job format in the queue, moving some scenarios to a separate handler, the order of dependent calls. In practice, a pause for the queue to drain and one restart are enough.
The main risk of changes is a "noisy" method: a mass export consumes the request budget and slows down other scenarios. Separate queues and a per-scenario quota help.
The second risk is non-idempotent write retries: after a timeout the call goes again, so the job is marked with a key, and the retry does not create duplicates.
Technical questions about request limits
Request limits in Bitrix24 rarely break the exchange out of nowhere — failures begin at peak times, when background exports coincide with employee actions. We have collected the questions most often asked before work starts.
What to do if the load falls during working hours?
Requests are queued with priorities: employee actions go first, reference data exchange runs in the background. The peak is spread over time, the quota is not consumed entirely, so short bursts do not lead to failures.
Should already rejected operations be resent?
Yes, but selectively. In the log, the operation receives a confirmation marker; resending occurs only for unconfirmed ones and with an increasing pause. Resending is idempotent — duplicated documents do not appear in accounting.
Will a separate middleware between systems be needed?
Usually not: the queue and retry accounting live inside the integration service. Separate middleware is needed when the stream is spread across several sites and must be coordinated centrally.
Will the exchange stop during implementation?
Work is done in a test environment — a copy of the portal with depersonalized data. The switchover fits within a maintenance window, and the previous mode remains as a rollback in case of discrepancies.
Will synchronization speed drop?
It will more likely increase: currently time is spent waiting after failures and on manual restarts. Batch processing and parallel streams within the quota shorten the exchange window, and some exports move to off-peak hours.
Let's discuss the task and come back with an estimate and plan
To come back with an estimate and plan, we need your picture of the exchange. Describe which systems are connected to the Bitrix24 portal — accounting system, warehouse, external services — where failures occur, and during which hours the load rises above normal.
Volumes matter: how many records go out per day and in what batches, which exchange is critical, and which is moved to a nightly window. Add who on your side supports the integrations and what access you are ready to provide.
Then we assemble the scope of work — from diagnostics to handover to operation:
- integration map and load profile: which methods are called, at what frequency, in which windows;
- request rate limiting scheme: general and per-user limits, queue, priority for critical scenarios;
- failure handling: retry with increasing pause, separate queue for heavy exports, analysis of limit errors;
- caching of reference data and recurring selections — some requests never reach the service;
- monitoring: failure share, queue length, waiting time — with alerts before the exchange stops;
- procedures and documentation: limits, exchange windows, rules for manual resending of lost records;
- stage timelines as separate milestones and post-implementation support: limit adjustments as volumes grow, incident analysis.
The estimate and plan come with a breakdown by scope of work and stage timelines, without vague wording. Let's discuss the task and start with the area that removes failures fastest.

