Skip to content

Rate Limiting

Milo Cesar edited this page Aug 30, 2020 · 1 revision

This plugins has had quite some issues with rate limiting #4, #17, #42, #49, #50, #54, #58. Since many questions about rate limiting still remain, I would like to give some explanation about it here.


What is rate limiting?

Rate limiting is a tool for server owners to limit the amount of times something can request data in a given period.

Why does rate limiting exist?

In computer networks, rate limiting is used to control the rate of requests sent or received by a network interface controller and is used to prevent DoS attacks.
~ Wikipedia

If a server gets too many requests, legitimate or illegitimate, the server will break and will be unable to process any requests. To counter this, server owners implement rate-limiting. This ensures that everybody can get their fair share of data in a timely fashion.

Who decides how many requests you can send?

The entity that owns the server can set these values. The rate limiting that is affecting this plugin is setup by Tuya.
Please note that this plugin is not created, verified or endorsed by Tuya. This also means that the maintainer of this plugin cannot alter these values.

How does the rate limiting for Tuya work?

This plugin uses 2 (rate-limited) requests, each have their own rate-limiting applied. The actual values can be found in the code.

Polling

The first one is for device discovery, this is used to see what devices are currently linked to your account. This request is used for everybody on homebridge startup. If you have the polling functionality enabled this value is also used to determine the minimum interval between polling. At the time of writing this value is 5 minutes (300 seconds). To ensure that you will not get the dreaded "Requesting Too Quickly" error this plugin backs off for 5 more seconds thus resulting in a minimum time between polling of 305 seconds. Any value lower than this will trigger the error and prevent you from getting any updates!

Standard request

The second type of request is the standard device request. This one gets triggered when you open Home.app or ask Siri what the state of your device is. We can fire this request (at the time of writing) every minute (60 seconds). Once again to prevent the error from triggering we add an extra 5 seconds back off window and actually fire the request at most every 65 seconds. There is no configuration value for this.

What happens when we can't request data due to rate-limiting.

This plugin assumes that we can always request data at least once, at the startup of homebridge. At this moment the plugin generates a list of all devices and their state. It sends this list to HomeKit but also keeps a copy for itself (a so-called cache). If you where to request the status of a device within 60 seconds (for example due to force-closing and re-opening Home.app) the plugin will refuse to request the data again at tuya's servers (since it knows it will get the error and thus requesting the data would only work counter intuitive). Since Home.app would still like to know the status, the plugin looks at the list it just copied and return the last known status.
If you where to request outside of the 1 minute threshold, the plugin will contact the tuya servers to request the latest status. When it successfully retrieves that status it will respond to Home.app with the newly retrieved data and update its internal list with the new data.

When I open the home app, the device shows a wrong state!?

Please read the parts above, you are probably requesting the state of the device too quickly and the plugin is returning data from its cache instead of from the tuya servers.

I want this plugin to always report the correct state!

As I tried to explain in the other parts, there is nothing I (the plugin maintainer) can do about this. The plugin requests the data as quickly as possible. Any faster would return in more errors and be counter productive.