Non deterministic and inconsistent rate limit of 10 orders/sec

explorer
I trade large quantities and have been using API for couple of years now to place 40+ orders at any given point in time. Since last 4-6 months, I have started observing rate limit errors for order placement API. I implemented client side throttling 2 years ago where max 9 orders are placed per second with gap of 1 second between bursts. The implementation never resulted in "Maximum allowed order requests per second exceeded" errors in year 2025.

Interestingly, around May 2026 I started receiving many failures everyday due to too many order requests error. Observing that, I changed the throttling config to place 8 orders/second and then 6 orders/second. Changing from 8 to 6 orders per window reduced error rate but it was never zero.

Here is how the throttler works:
1. Accept all orders
2. Place 6 orders in burst
3. Wait 1 second
4. Place next 6 orders

Then I did few more experiments to understand rate limiter but with no complete success. The only way I was able to submit multiple order bursts was by increasing the window size to 1800ms and dropping orders per window to merely 7, down from 10. Following is one such log where 7 orders are placed every 1250ms. As you can see, first burst(1-7) was placed by 24.194 and the next burst (8-14) was placed after 1.2s at 25.439. This should have resulted in all successes. However, requests 13 and 14 failed. There is no explanation why requests 13, 14 failed despite being submitted after 1 second than the previous burst.

Timestamps in hh:mm:ss.SSS format.
7 orders per window, 1250ms window size

14:35:24.187 sending request number 1
14:35:24.191 sending request number 2
14:35:24.191 sending request number 3
14:35:24.192 sending request number 4
14:35:24.193 sending request number 5
14:35:24.193 sending request number 6
14:35:24.194 sending request number 7

14:35:24.341 request number 1 placed successfully
14:35:24.342 request number 2 placed successfully
14:35:24.351 request number 7 placed successfully
14:35:24.353 request number 4 placed successfully
14:35:24.387 request number 5 placed successfully
14:35:24.389 request number 3 placed successfully
14:35:24.395 request number 6 placed successfully

14:35:25.439 sending request number 8 (2nd burst after 1st burst was accepted and placed successfully)
14:35:25.440 sending request number 9
14:35:25.442 sending request number 10
14:35:25.443 sending request number 11
14:35:25.444 sending request number 12
14:35:25.444 sending request number 13
14:35:25.445 sending request number 14

14:35:25.466 request number 13 failed due to too many requests error
14:35:25.467 request number 14 failed due to too many requests error
14:35:25.467 request number 9 placed successfully
14:35:25.468 request number 10 placed successfully
14:35:25.469 request number 8 placed successfully
14:35:25.470 request number 12 placed successfully
14:35:25.470 request number 11 failed due to too many requests error

14:35:26.690 sending request number 15 (third burst)
14:35:26.718 request number 15 placed successfully
My observations suggest that rate limiter is not using known rate limiter algo viz. sliding window, sliding window log/counter, leaky/token bucket.

It would be very helpful if Kite team clarifies:
1. What algorithm is used for API/orders rate limiting?
2. What is the configuration for the algorithm?
3. The reason I am seeing inconsistent API responses?
4. What changed in 2026 vs 2025 that has suddenly caused order rejection considering no client changes.

Thank you for reading!
  • salim_chisty
    Based on the logs shared, it appears that more than 10 order requests were being submitted within a one-second interval, resulting in the rate-limit rejection. Please ensure that your implementation strictly adheres to the prescribed 10 orders-per-second limit. The rate limit works on a sliding window basis.

    There have been no changes to the rate-limiting algorithm for such rejections. You can handle these responses programmatically using HTTP status code 429 (Too Many Requests) and implement appropriate retry/throttling logic. You may refer to the similar discussion here.
  • explorer
    @salim_chisty instead of pointing vaguely that more than 10 orders were submitted, can you explain clearly which orders you referred to? I have checked multiple times and there is always more than one second gap between last order of the batch and the new batch.

    For example, request 7 from first batch was submitted at 14:35:24.194, while the next batch was submitted at 14:35:25.439 which is 1.2s gap. Where do you see smaller than 1s gap?
  • explorer
    Moreover, I have verified that 10 orders / second are allowed only when they are spaced 100ms apart. The problem is burst/batch requests despite being separated by more than 1 second.
  • explorer
    @salim_chisty can you please kindly point out which 10+ orders were in 1 second window?
  • suprxd
    I can't say why this started happening suddenly but I am pretty much sure this is because you are implementing fixed window based rate limiter on your end whereas Kite has rolling 1 sec rate limiter.
  • suprxd
    I don't know what Kite has implemented but it's better to have sliding window log based approach on your end to stop this.
  • suprxd
    I know Kite APIs sucks given they are still using v3 from 2022 or before.
    There are lot of things they can improve but it's pathetic.

    I am using a mock Kite server to test such edges.
    You can build it via Claude and test if your approach passes otherwise we can write them email.
  • explorer
    explorer edited August 26
    @suprxd i have already verified my timestamps with multiple LLMs before posting here. Order batches are spread out by more than 1 second. There is no reason why would Kite reject such requests. Rolling/sliding/sliding log/counter, none of the algorithms match.

    Zerodha has implemented some kind of penalty for order bursts.

    Where can we send email about this?
  • salim_chisty
    @explorer, please share your Client ID with us via DM to check and assist you further.
  • explorer
    Thank you for following up on this! I have sent you DM. Included a Node.js script that reproduces the behavior.
  • salim_chisty
    The documented rate limit should be treated as a hard upper limit, rather than a rate at which an application should continuously operate, particularly when requests are being made concurrently or in bursts.

    When operating very close to the limit, the timing of requests can overlap at the server side even if the client-side timestamps appear to be more than a second apart. We tested the rate-limiting behaviour independently, and it is working as intended.

    For applications that generate concurrent order requests, we recommend maintaining sufficient headroom below the maximum rate. As a practical guideline, operating at around 60–70% of the documented limit provides a reasonable margin and reduces the likelihood of 429 responses during bursts or timing variations.

    Applications should also handle HTTP 429 responses appropriately, using backoff before retrying.
  • explorer
    @salim_chisty this contradicts with the rate limits advertised in the FAQ section that entire Zerodha team keeps pointing to. The rate limit mentioned is 10 orders / second while not clarifying whether it is burst rate limit or otherwise. This is the same limit mentioned on https://www.kite.trade/docs/connect/v3/exceptions/

    Considering the scale of position size I am operating at, there is real impact to my trading account when I am not able to exit the position in market runaway situation where system SL is hit (orders not placed to Zerodha as limit orders) resulting into worse fill and ultimately slippage. This is tested, verified and hence this thread was created.

    Can you please clarify following:
    1. What parameters were used in your testing? What was order burst size, and window length?
    2. You mentioned the behaviour is as intended. What is the intention?
    3. 6 orders burst size does not reliably result into all successful orders as I have proved in my first message in the thread. This is inline with your guidance that 60-70% of order limit should be followed. Despite being 60%, I still see order failures. Increasing it to 70% will result in even more.
    4. Why have you decided to penalize order bursts, while staggered 10 orders / second (i.e. 1 order every 100ms) go through successfully?
    If I am repeatedly getting worse order fills due to Zerodha not supporting nominal order burst size, I will have to move my portfolio and trading to other brokers as the last resort. I have no other complaints of Kite API but order bursts not playing well is a deal breaker when there is real money impact.
  • Nivas
    Nivas edited September 1
    Prior to April 1st, 2026, the rate limit was a soft limit, which could allow more than 10 requests per second. It is now enforced as a hard limit of 10 orders per second, in accordance with the applicable exchange regulations.

    In your case, the requests are being sent concurrently. The rate limit is evaluated based on the requests received by the API within the applicable sliding window, so client-side timestamps alone cannot be used to determine exactly how the server-side rate-limit calculation will evaluate those requests.

    The important point is that short bursts themselves are not prohibited. A burst of orders should be allowed as long as the number of requests falling within the applicable rate-limit window does not exceed 10 requests per second. The rate limiter is not intended to penalize a burst simply because the requests are concurrent.

    Therefore, if a burst of 6 or 10 orders is resulting in HTTP 429 responses even though the requests fall within the documented 10 orders/second limit, we would need to investigate this against the actual server-side request timestamps and rate-limit calculation. Please raise a support ticket with the complete request/response logs, including precise timestamps, so that we can verify the server-side rate-limit behaviour and assist further.

    We cannot increase the limit beyond 10 orders/second, as this is a regulatory requirement. If a strategy needs to place more than 10 orders per second, the strategy would need to be registered with the exchange. For more details, please raise a ticket.
  • explorer
    Hi Nivas,

    Thank you for thorough reply. If it was not clear from my previous messages, nowhere I have asked to relax the limitation of 10 orders/second. All I have been complaining about is, despite staying within the said limit, the orders are rejected with HTTP 429.

    I have prepared minimal reproducible steps in following Node.js script which fires 10 orders in batches. The batches are separated apart by 1550 ms gap which is much longer than advertised 10 orders/second limit. Script places 10 GTT orders and then waits 1.5 seconds to process the next batch so none of the orders should be rejected. However, 4-5 orders consistently get rejected. Following is the log to prove the same.

    23:44:45.157 sending request number 1
    23:44:45.249 sending request number 2
    23:44:45.251 sending request number 3
    23:44:45.253 sending request number 4
    23:44:45.256 sending request number 5
    23:44:45.258 sending request number 6
    23:44:45.260 sending request number 7
    23:44:45.261 sending request number 8
    23:44:45.263 sending request number 9
    23:44:45.267 sending request number 10
    23:44:45.328 request number 2 placed successfully
    23:44:45.332 request number 1 placed successfully
    23:44:45.334 request number 5 placed successfully
    23:44:45.338 request number 3 placed successfully
    23:44:45.342 request number 6 placed successfully
    23:44:45.346 request number 10 placed successfully
    23:44:45.365 request number 4 placed successfully
    23:44:45.374 request number 9 placed successfully
    23:44:45.386 request number 7 placed successfully
    23:44:45.389 request number 8 placed successfully
    23:44:46.708 sending request number 11
    23:44:46.710 sending request number 12
    23:44:46.712 sending request number 13
    23:44:46.713 sending request number 14
    23:44:46.714 sending request number 15
    23:44:46.715 sending request number 16
    23:44:46.716 sending request number 17
    23:44:46.717 sending request number 18
    23:44:46.718 sending request number 19
    23:44:46.719 sending request number 20
    23:44:46.732 request number 19 failed due to error: HTTP 429 Too Many Requests
    23:44:46.733 request number 16 failed due to error: HTTP 429 Too Many Requests
    23:44:46.734 request number 12 placed successfully
    23:44:46.735 request number 18 failed due to error: HTTP 429 Too Many Requests
    23:44:46.736 request number 11 placed successfully
    23:44:46.738 request number 14 placed successfully
    23:44:46.739 request number 17 failed due to error: HTTP 429 Too Many Requests
    23:44:46.739 request number 20 failed due to error: HTTP 429 Too Many Requests
    23:44:46.740 request number 15 placed successfully
    23:44:46.741 request number 13 placed successfully
    Please let me know your findings once you run the following script, which is well within the advertised limit of 10 orders/second. I think this script provides more value than me creating a support ticket as you can reproduce the behavior in your environment quickly.

    I am sure you are aware how to execute the script but if others are interested, here is how to run it:
    1. Rename the .txt to .js
    2. Update API_KEY and ACCESS_TOKEN appropriately.
    3. Execute with Node.
  • Nivas
    To investigate this further, we would need the relevant client/account details to cross-validate the requests and server-side rate-limit behaviour at our end. These details should not be shared on a public forum.

    As mentioned earlier, client-side timestamps alone cannot be used to determine exactly how the requests were evaluated against the server-side rate-limit window.

    While the script and logs are useful for understanding the scenario, we need the request details from our systems to verify what happened for the specific account. Hence, please raise a support ticket and include the script, complete logs, and the relevant timestamps. We can then check the details and assist you further.
  • explorer
    I have to disagree on what you said about client-side timestamps cannot be used to determine how requests are evaluated. If orders are spaced out by 100ms, all orders are accepted but not the order bursts despite being separated by more than one second.

    As 100ms orders are accepted, we cannot conclude that the order bursts client side timestamps are an issue. I have reproduced this issue on 2 separate accounts so far.

    I will open up a support ticket.
Sign In or Register to comment.